699 KiB
UX/UI: протокол внешней приёмки 12.5
Актуальное продолжение 2026-10-14: блок220 завершён. GRE catalog/config snapshots/alert source используют одну модель подтверждённых operational flags. Unknown flags не превращаются в degraded/up. Local49, profiles14+6, production30, real up→down/degraded→up/Ping3/3×2 и source/UI прошли; own objects удалены. Первичный native401104.165.244.7 после перепроверки не повторился, причина неизвестна. Backend ux-gre220/compiled1056/source488 matched, frontend ux-routing218. Следующий221 — native GRE identity/duplicate guards для каталога и snapshots. Этап12.5 открыт.
IPsec78: реальный PSK responder established, mode-config198.18.78.10 и online=true подтверждены API; точные собственные объекты удалены. Сертификатный/DN online, late failure и history restore остаются открытыми. Отчёт, журнал.
IPsec79: сертификатный responder online=true/static mode-config198.18.79.250 принят; recordRevision=null после native patch даёт502/state=applied. Собственные объекты и private files удалены. Отчёт.
IPsec80: real restore staticIp/disabled, повтор без дубликатов, foreign-reference409 и cleanup приняты. Первоначальный неполный образ откатан; исправленный runtime healthy. Отчёт.
IPsec81: partial/unknown native fault injection, preflight конфликтов, typed Remote ID, удаление старого mode-config и isolated JWT/RBAC приняты. Рабочая авторизация не менялась, физический TCP disconnect не моделировался. Отчёт.
IPsec82: production certificate data plane/NAT Ping3/3, capped UDP3s, history group/egress и API server delete приняты. Baseline14 коллекций×2 восстановлен после route convergence; own/private fixtures удалены. Отчёт.
Routing83: disabled BGP/OSPF selected/raw409/probe0 и собственная eBGP Established пара с reject-all filters приняты; original routes/config preserved, own DB/native fixtures удалены. Отчёт.
OSPF84: real GRE Full adjacency/private routes/Ping3/3 и4 live PC/320px URL/browser checks приняты. Exact own cleanup и исходные7 коллекций×2 passed; runtime routing83 без новой сборки. Отчёт.
BFD85: Up/Full/own route/Ping,4 live UI и loss/withdrawal/recovery приняты; exact own cleanup8 коллекций×2 passed. Withdrawal5,245ms не подтверждает sub-second BFD timing; этот вопрос открыт. Runtime routing83 без новой сборки. Отчёт.
Паспорт стенда
Перед внешним запуском зафиксировать отдельные PostgreSQL и RouterOS тестовые устройства, версии server/client PostgreSQL и RouterOS, HEAD backend/frontend, роли пользователей, число экземпляров backend/планировщика/отправителей и способ их остановки. Для Telegram использовать тестовый чат, для остальных интеграций — тестовые endpoints и учётные записи. Зафиксировать ожидаемые изменения и способ восстановления стенда.
Пароли, JWT, REUI_LICENSE_KEY, DATABASE_URL, дампы БД и исходные приватные журналы хранить вне Git. В отчёт включать очищенные ответы, ID тестовых объектов, UTC-время, request ID, HTTP-код и проверенные изменения. Контрольный снимок данных должен позволять сравнить состояние до/после; успешный toast без независимой проверки не завершает сценарий.
PostgreSQL и восстановление
| ID | Сценарий | Проверяемый результат | Доказательство |
|---|---|---|---|
| PG-1 | Штатный bootstrap чистой тестовой БД и повторный старт | Миграции 0008/0009 отражены в schema_migrations; constraint допускает pending/processing/unknown/sent/failed; resolution_version неотрицательна. Повторный старт сохраняет данные | Версии, очищенный журнал миграций, контрольные строки и ограничения |
| PG-2 | GET /api/system/database/backup с mm:settings:admin | Архив сформирован pg_dump, открывается совместимым pg_restore; контрольные бизнес-записи/схема присутствуют | Размер/SHA256 архива, список объектов, receipt и предупреждения |
| PG-3 | POST /api/system/database/restore из доверенного тестового архива | Данные тестовой БД соответствуют архиву; последующая запись получает корректный новый ID. UI различает завершение restore и ошибки перезапуска listener/scheduler/event | Сравнение схемы/контрольных записей, проверка последовательностей, HTTP/UI |
| PG-4 | Ошибка внутри реального pg_restore | Восстановление не объявляется успешным. Проверить rollback по контрольным бизнес-строкам и схеме, отдельно проверить последовательности | Ошибка процесса, HTTP/UI и независимые запросы до/после |
| PG-5 | Два конкурентных backup/restore запроса | Advisory lock исключает конкурирующее выполнение; второй запрос сообщает конфликт | Два request ID, HTTP-коды, журнал фактических процессов |
| PG-6 | Длительная фоновая запись и UDP-приём во время подготовки restore | Подтверждена остановка всех writers и отсутствие записей в критическом интервале; после операции потребители восстановлены либо показано предупреждение | Процесс/worker lifecycle, счётчики приёма/записей, состояния jobs |
| PG-8 | Ошибка записи speed snapshot/history и потеря commit acknowledgement | Снимок/история атомарны; неизвестный commit не выдаётся за гарантированный rollback и не вызывает автоматический повтор native test | Состояние PG после восстановления соединения, runId, HTTP/UI |
| PG-7 | Неавторизованный пользователь и обычный settings writer | Backup/restore требуют settings admin, отказ происходит до выполнения процесса | 401/403, неизменные контрольные данные, отсутствие pg_dump/pg_restore |
Реализация: bootstrap, migrations, 0008, 0009, database operation, restore execution.
После12.5.15 приложение используетpg_dump -Fc, проверкуpg_restore --list, генерациюpg_restore --clean --if-exists --file иодинpsql -X --single-transaction --set ON_ERROR_STOP=on -c partition parent preparation -f SQL. Предварительнаяподготовкаиrestore находятсявобщейтранзакции. Транзакционный режим описан в документации PostgreSQL. Проверка пяти байтов PGDMP проверяет заголовок, но не полноту и не доверие к архиву. Для rollback нужен сценарий с ошибкой исполнения restore, а не только отказ HTTP до его начала.
В локальном блоке12.5.8 добавлено ожидание текущих scheduler jobs с закрытием admission, но этот код ещё не развёрнут на стенде673e5ba. Блок12.5.9 добавляет отдельный graceful shutdown worker для database operation, serial flush, pool.end и обязательные acknowledgement/exit0. Локальные protocol tests и настоящий isolated collector/UDP/blocked SQL drain12.5.10 прошли: evidence. Основной код на стенде ещё не обновлён; app-wide quiescence этим не подтверждена. Блок12.5.11 локально добавляет admission/drain всех API handlers иtraffic live streams; новые tests/build passed, на стенде patch не развёрнут. В12.5.12 локально добавлен общий background registry/drain дляbackup/audit/certificate/partition maintenance/cache work, атакжеpause RIPE enqueue. Tests/build passed; В12.5.13 добавленcache invalidation послеуспешногоrestore идоconsumer restart, локальныесовместныеhelpers tests passed. Всяцепочка требуетreal-PG integrated quiescence/restore12.5.14. Основнойстенд покаsource673e5ba. Другие экземпляры/хосты требуют отдельного контроля. PG-6 остаётся открытым до наблюдаемого подтверждения; восстановление стенда выполняется после его получения. Реальные тесты backend, способные очищать таблицы, запускаются только против выделенной тестовой БД.
После bootstrap достаточно следующих запросов чтения для начальной проверки, без вывода секретов:
SELECT id FROM schema_migrations
WHERE id IN ('0008_alert_outbox_outcomes', '0009_alert_outbox_resolution');
SELECT status, count(*) FROM alert_outbox GROUP BY status;
SELECT min(resolution_version), max(resolution_version) FROM alert_outbox;
Очередь уведомлений и Telegram
| ID | Сценарий | Проверяемый результат |
|---|---|---|
| Q-1 | Два конкурентных claim одной записи | Один sender получает право отправить; duplicate claim не отправляет второй запрос |
| Q-2 | Telegram принял сообщение, затем settlement/history transaction отказала | Ответ Telegram не подменяет DB receipt; запись удерживается в unknown/processing, автоматического повторения нет |
| Q-3 | Timeout после возможной отправки | UI сообщает неизвестный исход; сообщение в чате и состояние БД проверяются независимо |
| Q-4 | POST /api/alerts/outbox/:id/retry для unknown с текущим expectedVersion | Одна транзакция переводит запись в pending и увеличивает resolutionVersion ровно на1; stale version даёт409 без нового изменения |
| Q-5 | Повтор processing или unknown без подтверждённой остановки всех отправителей | Processing не разрешается вручную через этот API. Перед повтором unknown зафиксированы остановка всех senders и осознанный риск дубликата |
| Q-6 | Два enqueue с одинаковым dedupe key | В PostgreSQL создана одна запись; нет двух отправок из-за race |
| Q-7 | Нарушение прав, malformed receipt, изменение источника при pending | Отказ до действия; UI сохраняет checkpoint/черновик и не переносит результат в другой источник |
Для Q-1/Q-6 нужны конкурентные соединения реального PG; in-memory DI не доказывает изоляцию. Для Q-2 проверить атомарность status/history при ошибке внутри транзакции. Остановка senders подтверждается процессами/контейнерами и завершением in-flight requests; checkbox, timeout и отсутствие недавних логов достаточным доказательством не являются. Различать принятие Telegram API и прочтение пользователем.
Источники: outbox, delivery, retry, HTTP.
RouterOS и сетевые операции
| ID | Сценарий | Проверяемый результат |
|---|---|---|
| ROS-1 | Bandwidth-test transmit/receive/both на паре тестовых устройств | Реальный REST shape содержит native completion; TX — отправка клиента, RX — приём. Неизмеренная сторона null, измеренный0 сохраняется |
| ROS-2 | Authentication failed, unreachable, busy, disconnect и прерванный тест | Backend не пишет done и не заменяет старые probe averages; error run/HTTP/UI согласованы |
| ROS-3 | Выбранный srcInterface и тест скорости | Независимо проверить маршрут bandwidth-test и interface after-ping. UI не выдаёт выбор Ping-интерфейса за доказательство WAN скоростного теста |
| ROS-4 | Home→JH и JH↔Exit с асимметричной скоростью | Направления DL/UL соответствуют клиентской стороне; model limits применяются к правильному направлению |
| ROS-5 | OSPF preview → действие → перечитывание templates | Preview соответствует исправленным RX/DL и TX/UL. Применение подтверждается фактическим cost; частичный отказ не становится полным успехом |
| ROS-6 | WireGuard/IPsec/GRE/VXLAN/Firewall/BGP/маршруты | Проблема→устройство→форма→подтверждённое действие→возврат сохраняет контекст. Права и повторное нажатие проверены; фактическая конфигурация и connectivity сверены |
| ROS-9 | Смена пары или параметров измерения в каталоге и конкурентное завершение native test | Новый snapshot unknown, старый run сохранён с actual endpoints; enable/reorder сохраняют измеренный0. Проверить row locks/условный UPDATE в реальном PG |
| ROS-8 | Смена пары, интерфейсов, протокола, направления, длительности или удаление speed-пробы до запуска и во время теста | Preflight409 до команды; при поздней смене новый snapshot не перезаписан, actual run сохранён без stale probe association |
| ROS-10 | POST speed-test и последующий GET истории/пробы с разными часовыми поясами браузера и сервера | createdAt сохраняет серверный instant и совпадает с записью; nullable Ping не становится timeout. Это время перед after-ping, не начало bandwidth-test; legacy receipt без createdAt отдельно обозначить в evidence |
| ROS-7 | Удаление/отсутствие доступа/частичный отказ одного устройства | Ошибка не стирает форму, последний снимок и объекты остальных устройств; неизвестные метрики не превращаются в0 |
Для ROS-1/ROS-2 зафиксировать версию RouterOS и очищенный сырой ответ. Строковый status подтверждается по официальному CLI reference; несовместимый REST shape требует отдельной коррекции контракта. Тест скорости способен нагрузить канал — длительность и endpoints выбираются для выделенного стенда. Команды и правила маршрутизации этой UX/UI-серией не расширялись.
Остальные интеграции
| Область | Минимальная реальная проверка |
|---|---|
| MaxMind/RIPE | Валидный ответ, отказ/timeout, свежесть источника и неизвестное значение; реальные данные сверены с тестовыми адресами |
| Portal/Evolution | Настоящие роли/JWT, истечение/отзыв прав, scope приложения и смена backend; отказ происходит до операции |
| Сертификаты/S3/контейнеры | Реальный job/файл/объект и права после receipt; ошибка/частичный исход, восстановление контекста |
| Gitea/CI/релизы | Сборка и delivery в выделенном стенде, отображение фактического статуса и версия. Git-коммиты текущей задачи остаются локальными; публикация — отдельное действие |
BGP-prefix evaluator, отдельное live GRE расписание и recovery processing не считать реализованными по UI или локальным тестам: текущие ограничения описаны в журналах11Б/12.
Запись результата и критерий завершения
Для каждого ID сохранить: HEAD, UTC, идентификатор стенда/версию, роль, исходное состояние, действие, HTTP/native receipt, независимо подтверждённое итоговое состояние, результат passed/failed/blocked, способ возврата стенда и ссылку на очищенное доказательство. Пример строки:
| ID | HEAD / стенд | Доказательство | Результат | Следующий шаг |
|---|---|---|---|---|
| ROS-1 | Заполнить при запуске | Очищенные native rows + GET истории + снимок UI | Не выполнен | Проверить transmit/receive/both |
12.5 закрывается после выполнения обязательных сценариев и разбора отказов на согласованном стенде. Подготовленный протокол, успешные browser/DI tests и автоматический axe-аудит не заменяют внешние результаты или ручную работу со screen reader.
Обнаруженный блокер restore — 2026-10-07
12.5.14 realAPI/sourcef1aac49 навыделеннойPG18.6 подтвердилadmission/drain,ноrestore400 из-заinheritedpartitionPRIMARY KEY при--clean. Evidence/rollback controls. PG-4 подтверждёнвграницахнастоящейSQLошибкииконтрольныхстрок/sequence/constraint; PG-3успех/последующийID иполныйPG-6 непроверены. Следующий12.5.15 исправляеттранзакционнуюочистку. Основнойruntime673e5ba сохранён.
Restore исправлен — 2026-10-07
12.5.15 realAPI200/контрольархива/новыйID3 иinjectedCREATE INDEX400/rollback данных,sequence и1587constraints прошли: evidence. PG-3/4 принятывэтихграницах, Portal/UI/fullchecksum не проверены. Основнойruntime673e5ba сохранён; integratedPG-6/deployment ещёпредстоят. Приrestart ресурсныйcollector попыталсяопрашиватьdisabledserver3; исправление12.5.16.
Политика выключенных серверов — 2026-10-07
12.5.16 по явномувыборупользователя убрал намеренноеHome Router исключение изuptime/RESTping; scheduledspeed игнорируетdisabledendpoint, manualspeedотказдосети. RealPG/CHRматрица passed. Основнойruntime673e5ba не обновлён;integratedPG-6/deployment12.5.17 впереди.
IntegratedPG-6 иdeployment — 2026-10-07
12.5.17 подтвердилsingle-instanceadmission/drainHTTP/UDP/scheduler/backgroundwrite,restore200 ивозобновлениеUDP. Deployment основнойbackend4c12c55healthy/контрольБДpassed,frontend673e5ba прежний. Multi-instance/Portal/browserrestore/остальныеинтеграции требуютпродолжения12.5.18.
RBAC иbrowser restore — 2026-10-08
12.5.18 realJWT/processPG-7 иbrowserrestore200/400/guard/reload прошли. ИзоляцияfrontendпроверяласьмаркеромБД:runtimeURLoverride не менялbakedNextrewrites,поэтомуиспользованавременнаяотдельнаяDocker network/backendalias. Основнойстенднеизменён,temporarycontainers/network/tunnelудалены. PortalSSO/commit-loss/PG-8/остальныеинтеграции ещёнеприняты.
PG-8 — 2026-10-08
12.5.19 realPG/nativeTCP матрица подтвердилаINSERTrollback иclient-sideackfault послереальногоCOMMIT,безложногоfailurewrite/повтора. API502unknown/runId;scheduledreceiptokfalse,история/snapshotdoneсохранены.18scheduler/16persistence/HTTP-RBAC/build passed. Это не физическийTCPdisconnect;browserunknown-speed/deploymentpatch ещё12.5.20. Основнойbackend4c12c55 сохраняется.
Локальный snapshot guard — 2026-10-08
12.5.20 сохраняетlastconfirmedspeed snapshot дляunknown502/совпадающегоrunId.2unit tests/frontendtypecheck passed;browserunknownUX ещёнепроверен,patchнеразвёрнут. Backend4c12c55/frontend673e5ba прежние. Следующий12.5.21 — build/browserunknown/deploymentобоихобразов.
Локальный unknown UX — 2026-10-08
12.5.21: отдельная строка unknown/runId, сохранение snapshot и сверка по идентификатору при чтении истории. 13 браузерных тестов с HTTP-моками/typecheck/ESLint прошли; это не приёмка real browser/PG. Основной backend4c12c55/frontend673e5ba прежний. Следующий 12.5.22 — сборка и проверка обновлённых образов. Полный 12.5 открыт.
Real browser unknown и deployment — 2026-10-08
12.5.22: real browser speed unknown подтвердил snapshot42, видимый unknown/runId, reconciliation к SQL history done, снятие предупреждения, native1/POST1/JS0/320fits. HTTP/RouterOS-моков нет; COMMIT acknowledgement fault введён на node-pg boundary, физический network disconnect не проверен. Оба образа8782054 развёрнуты, пять экранов прошли. Основная БД не восстанавливалась, контроль сохранён. Следующий12.5.23 — ROS-8/9: preflight/late-context changes на реальном PG/native. Полный12.5 открыт.
Real speed context — 2026-10-08
12.5.23 ROS-8/9 API/SQL/native evidence: семь preflight409/bandwidth0, enable/reorder сохраняют fixture0; три TCPtransmit3s теста при late change/delete/row lock. Фактическая history done сохранена без stale probe association, новый snapshot null. Scheduler admission закрыт в isolated process до fixture setup; основной backend8782054healthy/история5 сохранены, testprobes0/containerудалён. Browser race и multi-instance открыты. Следующий12.5.24 — browser-смена контекста вторым клиентом.
Browser speed context — 2026-10-08
12.5.24 real browser/native: смена пары/длительности и удаление независимым HTTP-клиентом до native response; UI refresh/reload сохраняет новый контекст без старых скоростей, history done остаётся. Принятые native2/POST[200,200]/JS0/320fits, без HTTP/RouterOS-моков. Ещё один native command выполнен в подготовительном прогоне с неверным UI selector expectation; application auto retry отсутствует. Temporarycontainers/network/3018 закрыты, testprobe удалена; runtime8782054/основнаяhistory5 сохранены. Следующий12.5.25 — ROS-2 authentication failure.
Реальный отказ bandwidth-аутентификации — 2026-10-08
12.5.25 native/API/browser evidence: authentication failed→HTTP502/русская UI-ошибка, history error/TXRXnull; probe previousTX42 сохранён. Native1/POST[502]/refresh/reload/320fits/JS0, без HTTP/RouterOS-моков. Тестовое имя изменялось только в выделенной app DB и восстановлено; RouterOS accounts не менялись. Temporarycontainers/network/3018 закрыты, testprobe удалена; основнаяhistory5/runtime8782054 сохранены. Подготовительный слишком длинныйuser отклонён по длине; accepted run отдельно. ROS-2 authentication failure принят; остальные native failures ещё открыты. Следующий12.5.26 — unreachable destination.
Исправление Next proxy timeout — 2026-10-08
12.5.26 real frontend500/backend error-history выявил30s proxy timeout. Локально proxyTimeout180s; реальная Next proxy regression31s/TypeScript/ESLint passed. Backend сохраняет предыдущий TX42; native can not connect не подтверждён. Runtime8782054 прежний; destination восстановлен/testprobe удалена/temporarycontainers-network-3018 закрыты. Следующий12.5.27 — build/real browser retry/deployment исправленного frontend.
Новый frontend proxy timeout — 2026-10-08
12.5.27 real browser timeout502, frontend deployment, пять экранов passed. Frontendaa7dbdf/proxy180s, backend8782054healthy прежний; MMAPP_IMAGE_TAG=ux-aa7dbdf/BACKEND_IMAGE_TAG=ux-8782054. Основной DBcontrol совпал. Isolatedhost/probe восстановлены/удалены, temporarycontainers/network/3018 закрыты. Это transport timeout, не native can not connect; техническая подпись timeout остаётся ограничением UX. Следующий12.5.28 — ROS-3 interface/address/after-ping.
Интерфейс native test и Ping — 2026-10-08
12.5.28 real ROS-3: reverse2→1 done, bandwidth194.226.121.150/nointerfacebinding, Pingether1/0%loss; metadata source195 не доказываетsourceIPpackets. CHR2 имеет dynamic104/static195, явныйdstinterface предпочитаетstatic. Три1→2 попыткиtimeout, причинаauto-path не установлена; они не приняты. КонфигурацияRouterOS не менялась. Основнойruntimebackend8782054/frontendaa7dbdf/history5 сохранён. UIhint/CLIwhereinterface исправлены локально; browserfixture/typecheck/ESLint passed, не развёрнуты. Следующий12.5.29 — real browserform/deploymentподсказок.
Форма интерфейсов развёрнута — 2026-10-08
12.5.29 real browser form, deployment, пять экранов passed. Frontendf194e72, backend8782054healthy прежний; MMAPP_IMAGE_TAG=ux-f194e72/BACKEND_IMAGE_TAG=ux-8782054. Настоящий inventory/static-IP195, правильныйCLIinterfacefilter/пояснение/320fits/JS0, без моков/native-команд. Основнойcontrol совпал; fixtureprobe/temporarycontainers/network/3018 удалены. Следующий12.5.30 — read-only forward-native диагностика; timeout1→2 не исправлен этим UI-изменением.
Read-only forward диагностика — 2026-10-08
12.5.30 settings/state, jobs, TCP2000 сDebian. Server enabled/authtrue/session0, filter/NAT/mangle0, active main default routes, CPU0; TCP2000 reachable сDebian. ПричинаCHR1→CHR2timeout не установлена. Поздние REST401/CHR2-500 ограничивают дополнительные чтения. Native0/configchanges0, temporarycontainers завершены, mainruntimebackend8782054/frontendf194e72/history5 сохранены. Следующий12.5.31 — CLI/REST/соединения1→2, без изменения адресов и маршрутов.
Текущий доступ CHR2 требует проверки — 2026-10-08
12.5.31 CLI/REST/SSH comparison: CLI3.5s/REST3.0s nativeauthenticationfailed; GETconnections401, SSH2AuthenticationException. Main/testcredentials совпадают, значения не раскрыты. Текущий отказ авторизации подтверждён; причина прежнегоtimeout не доказана. Запрошены актуальные данные или проверкаadmin на104.165.244.7, зависимаяприёмка ожидает ответа. RouterOSconfiguration не менялась, mainruntimebackend8782054/frontendf194e72/history5 сохранён. Независимые12.5 сценарии остаются открытыми.
Доступ восстановлен пользователем — 2026-10-08
12.5.32 API/native1→2, realbrowserdashboard passed. Пользователь восстановил парольCHR2; агентне менялRouterOSaccounts/credentialsприложения. Четыре каталога200/failures0, прежниеошибкиUI отсутствуют; nativeTCPtransmit3s1→2 done/HTTP200/53ms0%loss/однаhistorydone. Mainhistory5→6 намеренно; runtimebackend8782054/frontendf194e72 прежний. Старыеисторическиеошибкине переписаны; источник измененияпароля/все прежниеtimeouts не установлены. ОжиданиедоступаCHR2 снято, следующие12.5сценарии ещёоткрыты.
TCP directions после восстановления — 2026-10-08
12.5.33 receive/both native/API/history passed: две TCP3s команды1→2, HTTP200/done testing, receiveTXnull/RXmeasured, bothTXRXmeasured, Ping53ms0%loss. УникальныеGEThistory строки совпали сAPI; mainhistory6→8 намеренно. Это функциональные значения, неbenchmark. Runtimebackend8782054/frontendf194e72/RouterOSconfiguration прежние. Следующий12.5.34 — ограниченныйUDPtest; остальные12.5сценарии открыты.
UDP native/API/history/UI — 2026-10-08
12.5.34 UDPtransmit3s passed: HTTP200/native done testing, TXmeasured/RXnull, Ping53ms0%loss; independenthistory/realbrowserUDP/done/unknownRX/320fits/JS0. Mainhistory8→9 намеренно. Rate cap не задавался, ограничение поduration3s; packet-deliveryratio/benchmark не заявлены. КонфигурацияRouterOS/пароли/runtimebackend8782054/frontendf194e72 прежние. Следующий12.5.35 — Q-6 PostgreSQL dedupe без реальнойотправки сообщений. Остальной12.5 открыт.
Q-6 dedupe — 2026-10-08
12.5.35 productionenqueue/PG race passed:2blockedINSERTs/receipts true-false/однаpendingстрока/повторfalse. Fixtureудалена/countbaseline восстановлен; dispatcherне запускался/сообщений0, mainruntime прежний. Q-6 принят; следующий12.5.36 — Q-4 unknownretry/version без отправки.
Q-4 retry/version — 2026-10-08
12.5.36 realHTTP/PG passed:2blockedUPDATE/200-409/version0→1; stale409, processing409, ackfalse400, отказанныезапросыне меняютстроку. Fixtureудалена/baselinecount восстановлен, app/pool/containerзакрыты, dispatcherне вызывался/сообщений0. Q-4 принят; Q-5 толькоprocessing-refusal. Runtime/mainhistory9 прежние. Следующий12.5.37 — конкурентныйclaimQ-1; реальныеTelegramdelivery scenarios требуютсогласованногочата/разрешенияна сообщения.
Malformed retry receipt rollback — 2026-10-08
12.5.36.1 realPGtrigger/HTTP500/SQLrollback passed: version2 отклонена, unknown/version0 сохранены. Fixture/trigger/functionудалены, app/pool/containerзакрыты, сообщений0. Runtimeпрежний; полнаяQ-7/Telegramприёмка открыта. Следующий12.5.37 — Q-1claim после проверкилимита.
Q-1 production claim — 2026-10-08
12.5.37 realPG/productiondispatcher passed:2blockedclaims/interceptedsender1/sentfixture1/history1/no duplicatecall. Реальныхсообщений0; fakeTelegramsettings/fetchзамена сняты, fixtureудалена/DBcountbaseline восстановлен. Q-1принятдляодногопроцесса/несколькихPGconnections, не реальнаяTelegramдоставка. Runtimeпрежний. Следующий12.5.38 — SQLsettlementfailure послеfixtureacceptedresponse.
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 (2026-10-09)
Подробный объём, протоколы, схема и ограничения: 12.5.77 в журнале.
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 сохранены для трёх фаз.
- Валидный external CRL для CA/client загружен: IKE/ESP established, Ping3/3, API online=true.
- Тот же 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.
- 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.
12.5.183 — понятная причина частичного сбоя peer-опроса (2026-10-12)
Optional WireGuard peer error больше не исчезает в catch. Collector сохраняет причину в текущей записи traffic_collection_state, snapshot.warning и trafficSettings.lastError. Успешный interface poll остаётся status=ok: известные interface скорости/история не теряются из-за ошибки отдельного peer endpoint. Перезапуск с корректным peer ответом очищает прежнюю причину.
Existing observations.error передаёт причину в DTO. ReUI Alert показывает «Часть измерений недоступна» при current measurements с предупреждением; при unknown/stale остаётся профильная подпись и та же причина. Manual collect response содержит warnings с serverId; event получает warning level и «завершён с ограничениями». Нового schema/state enum и миграции нет. Общий scheduler не объявляет interface poll неуспешным из-за optional peers; ограничение сохранено в его snapshot.
| Состояние | Схема | Результат |
|---|---|---|
| Interface success + peer401/invalid | measured rates + warning → пользователь видит часть недоступных данных | known0 остаётся0; peer Нет данных |
| Следующий полный poll | warning очищен → обычное текущее состояние | причина прежнего сбоя не остаётся ложной |
TypeScript/backend build/ESLint прошли.4 E2E11.2s:2 новых на1440/320 сохраняют measured0/history и показывают WireGuard401 reason,2 проверяют status TTL/legacy. Это API-fixture UI, не отказ реальных credentials.
Own PG SQL:53 cases9counter+14history+10TCP SSE+6volume+14status,37478ms, без skip.3 предыдущих malformed/duplicate/shape cases теперь также проверяют сохранение warning;2 новые — peer-only401 с успешным iface+DTO cause и recovery с очищением причины. Временная база/ограниченная role/container удалены; exact namespace и отсутствие отражены в публичном отчёте.
Source455/524/compiled1040 SHA256 parity. Обе production builds прошли. Frontend ux-warning183 сначала проверен с backend ux-peer182 interop, затем both ux-warning183 healthy/running/imageIds. Только .env tags; rollback frontend ux-status181/backend ux-peer182, без secret env copy.
Actual API/browser1440/320 подтвердили нормальный runtime/live/receipt labels без page errors/overflow. Оба CHR доступны в preceding182 native read; этот checker не отправлял новых native commands и не создавал искусственный отказ на реальных устройствах. Пароли/конфигурация не менялись, messages0. Туннельное соединение не заявлено: native peers182 были пустыми, fault/recovery доказаны в изолированном SQL/HTTP сценарии. Перезагрузить вкладку для нового Alert.
Следующий184 — явно определить покрытие периода при отсутствующих poll waves/переименовании или пересоздании интерфейса и не выдавать lower-bound за полный период. Внешние интеграции/масштаб и итоговая12.5 остаются открыты. Локальный коммит без push.
12.5.184 — сохранение истории после отключения интерфейса (2026-10-12)
Read-only baseline воспроизвёл потерю истории: ether1 имеет2048 known bytes, ether2 — measured0; когда последнее состояние ether1 inactive или disabled, серверная сумма становится0, тогда как explicit interface detail сохраняет2048. Active control даёт2048 в обоих случаях. Это следствие фильтра по последнему running/disabled, а не ошибка RouterOS counters.
Исторический builder больше не исключает весь ряд или delta по состоянию линка на конце интервала. Валидные соседние counter deltas учитываются независимо от последнего link state. Статусы/число активных sessions по-прежнему зависят от native running/disabled. Live monitor/collector snapshot sum и правила исключения loopback/peer остаются прежними. Rate из истории — среднее между counter measurements; это не instantaneous native live rate и не доказательство доступности линка. Reset/unknown counter pair не добавляет bytes.
| Сценарий | До | После |
|---|---|---|
| inactive/disabled ether1 + active ether2 с0bytes | общая сумма0, detail2048 | сумма/detail2048, sessions1 |
| оба active | сумма/detail2048 | 2048 без изменения |
Fixed formulas:3 control cases, input rows/source SHA сохранены; no device/DB writes. Own PG:55 cases9counter+14history+10TCP SSE+8volume+14status,36245ms, без skip.2 новых SQL cases проверяют GET server detail+summary, known history/peak и sessions1 после inactive/disabled last sample; seeded legacy counter-known flags не заявлены native status proof. Own namespace/role/container удалены и отсутствие проверено.
Backend TypeScript/build, source455/524, compiled1040 SHA256 parity passed. Backend ux-history184 healthy/imageId verified, frontend ux-warning183 без исходных изменений/повторной сборки. Только backend.env tag; rollback both ux-warning183. Actual API/production browser1440/320 passed с actual live/receipt labels, без ошибок/overflow. Checker не менял credentials/config и не отключал реальные интерфейсы CHR.2 CHR доступны по последнему native182; новые native commands API-checker0, messages0.
Следующий185 — оценка покрытия периода при пропусках и смене идентичности/пересоздании интерфейса. Подтверждённые bytes остаются учтённым объёмом, не полным billing за период; восстановление идентичности по одному имени не доказано.12.5/внешние интеграции открыты. Локальный коммит без push.
12.5.185 — граница доверия скорости после пропусков: baseline (2026-10-12)
Блок начат; реализация и приёмка не завершены. Чистый read-only пример проверил один и тот же достоверный delta1MiB между двумя counters с интервалами30s,90s,1h,24h. Учтённый объём во всех случаях1MiB — корректное свойство counter difference. Но observations.rxNow=true также для среднего за1h/24h; длительность последнего интервала пока не влияет на доверие текущей скорости. Это не native monitor-traffic: среднее за интервал не доказывает instantaneous rate в конце интервала.4 baseline cases не являются4 новыми принятыми production сценариями.
| Интервал | Текущий mask сейчас | Что проверить |
|---|---|---|
| 30s/90s | true | допустимый предел относительно trafficSettings.intervalSec |
| 1h/24h | true | текущая скорость unknown при слишком длинном интервале; history и known bytes сохраняются |
Точный следующий шаг: передавать длительность последней пары measurements в provenance и ограничить current counter-derived rate согласованным пределом относительно collector period. Аналогичный guard нужен в snapshot collector, чтобы новое чтение после длительного сбоя не объявляло старое среднее текущей скоростью. Подтвердить normal/threshold/long gap/recovery/reset на собственном SQL/HTTP и UI. Не подменять average/unknown нулём и не менять actual SSE monitor rate. Отдельно остаётся неоднозначность пересоздания интерфейса с прежним именем и увеличившимся counter: существующая sample identity не доказывает непрерывность.
Стенд остаётся backend ux-history184/frontend ux-warning183, source/runtime184 не менялись. Аудит не обращался к CHR/DB, writes0/native commands0, пароли/конфигурация не менялись. Состояние сохранено локальным коммитом без push для продолжения185 после сброса лимита.
12.5.185 — доверие текущей скорости после длительного пропуска (2026-10-13)
Завершает baseline185 от2026-10-12. Builder сообщает measurementIntervalMs последней пары counter samples; для агрегата используется максимальный интервал всех составляющих, отсутствие interval в одной из новых составляющих даёт null. applyTrafficFreshness разрешает текущую counter-derived скорость только при положительном конечном interval≤3×max(5s,configured period). Это тот же запас3периода, что у TTL. При периоде30s граница90s включительно; более длинный или неизвестный интервал даёт unknown и понятную причину. Историческое среднее и подтверждённые counter bytes сохраняются.
Collector использует тот же предел в observedTrafficRate: после длинного пропуска snapshot не содержит sumRxMbps/sumTxMbps как измеренную текущую скорость. Следующая нормальная пара восстанавливает current, включая measured0. Native SSE monitor-traffic не изменён; native link status не зависит от длительности counter pair. Legacy вручную сформированная meta без interval сохраняет прежнюю совместимость; production builder выдаёт interval/null явно. Это не подтверждение native identity или полного billing за период.
| Состояние | Схема | Проверка |
|---|---|---|
| 30s/90s | свежая пара → current | unit threshold |
| 90.001s/1h/24h | history+known bytes → текущая скорость неизвестна | unit, own SQL, UI1440/320 |
| Новый poll после пропуска | нормальная пара → current0 допустим | own collector/SQL recovery |
Unit threshold/invalid interval/merge/collector guards, backend/application TypeScript и ESLint passed.6 E2E14.7s (2new gap+2binding freshness+2peer warnings) passed. UI использует существующий ReUI Alert/base-nova без новой темы или компонентов. Owned SQL:58 cases9counter+14history+10TCP SSE+10volume+15status/37008ms, no unavailable skip.3 новые cases: API сохраняет1MiB/history при120s gap, API recovery30s возвращает current и2MiB, actual fixture collector long gap не выдаёт current sum и второй poll подтверждает0. Первоначальный SQL запуск выявил fixture duplicate PK при переносе всех исторических timestamps; fixture оставляет только последнюю волну перед сдвигом. Ошибка не выдана за passed, обе временные базы/роли удалены. Последняя ownDB mm_accept_166_1791827374886/role/container удалена и отсутствие проверено.
Source456/524/compiled1040 SHA256 parity. Backend production ux-gap185 healthy/imageIds, frontend ux-warning183 без исходных изменений/повторной сборки. Только backend.env tag, rollback backend ux-history184/frontend ux-warning183; secret env copy0, migration0. Actual API/production UI1440/320 passed с actual live и backend receipt labels, no errors/overflow. Checker не отправлял новых native commands и не создавал отказ на CHR. Password/config/message changes0.
Следующий186 — provenance native interface/peer identity и конфигурации источника: positive counter difference по одному прежнему имени не доказывает непрерывность после пересоздания/смены устройства. Старую историю не переписывать по догадке. Общая12.5 и внешние зависимости остаются открыты. Локальный коммит без push.
12.5.186 — подтверждение идентичности пары счётчиков (2026-10-13)
Имя интерфейса больше не является единственным основанием новой counter pair. Nullable native_counter_identity хранит нормализованные source.updatedAt и native RouterOS.id (*HEX). Producer подтверждает continuity только когда identity непустая и совпадает с предыдущей строкой того же interface/peer key. Новый native ID, конфигурация источника или missing/invalid ID дают первую pair unknown; следующий подтверждённый poll восстанавливает измерение. Для WG используются peer.id и существующий public-key/iface series key, не ID самого интерфейса.
Биты16/32 различают confirmed continuity и сам факт проверки новым producer; running/disabled/counter/status markers не меняют смысла. Builder исключает неподтверждённую или несовпадающую pair из новых rates/bytes, сохраняя остальные подтверждённые исторические пары. Первый корректный counter остаётся baseline для следующей pair, даже если его собственная предыдущая continuity неизвестна. Legacy rows не переписываются: absent new marker/native identity оставляет прежнюю явно ограниченную историю. Это не доказательство непрерывности legacy, повторного использования того же native ID после перезагрузки или физической доступности.
| Изменение | Схема результата | Проверка |
|---|---|---|
| Same name, новый native ID | old counter → unknown boundary → новый baseline → confirmed0 | own SQL interface+peer |
| Config version изменилась | не переносить counter pair между источниками → normal next poll | own SQL |
| Missing native ID | новые pair unknown, без guessed zero/bytes | own SQL/unit |
Миграция0012 добавляет nullable TEXT к partitioned traffic_samples, включая существующие partitions; нет массового UPDATE/переписывания flags. Downgrade старого reader может игнорировать новый столбец, migration removal не выполнялась. Реальный backup/restore с новой колонкой — следующий187, пока не принят данным блоком.
Unit identity/config/legacy-marker/pair guards, backend/application TypeScript и diff checks passed. Own PG SQL:62 cases9counter+14history+10TCP SSE+10volume+19status/37613ms, no skip.4 новые cases: interface ID replacement/config version/missing ID/peer ID replacement с positive counters, unknown boundary, no extra bytes и последующим measured0. Fixtures явно объявляют native IDs; VM actual-collector unit получил настоящий identity/peer parser dependencies вместо отсутствовавших globals. Первая попытка остановилась до SQL scenarios на прежнем VM fixture; временная база/role удалены. Последний namespace mm_accept_166_1791828561251/role/container удалён, absence verified.
Source458/524/compiled1040 SHA256 parity. Backend ux-identity186 healthy/imageIds; frontend ux-warning183 без изменений/новой сборки. Only backend.env tag, rollback backend ux-gap185/frontend ux-warning183; additive migration остаётся. Secret env copy0.
Native GET: оба CHR доступны, interface native IDs/flags/counters валидны;0012 applied. Peers фактически0 — positive peer replacement доказан изолированным fixture, не реальным VPN-туннелем. DB read-only/RouterOS config writes0/password changes0/messages0. Initial API ожидаемо unknown при первом baseline после нового writer; штатное восстановление подтвердило current/rxKnown/txKnown обоих CHR с30s interval без manual collector invocation. Production UI1440/320 actual live/receipt labels/no errors/overflow. Native SSE не изменён; предшествующие6E2E185 UI guard checks не пересчитываются как новые186.
Следующий187 — own-schema archive restore для nullable native counter identity/continuity flags и старого schema archive с повторным bootstrap migration. Потом отдельная приёмка многопроцессной координации/масштаба/внешних доступов.12.5 открыта. Локальный коммит без push.
12.5.187 — совместимость архивов после миграции counter identity (2026-10-13)
Воспроизводимый runner проверяет namespace/role/current_database до операций; допускает только отдельную mm_accept_166_* базу с ограниченной ролью. Реальные pg_dump/pg_restore/psql18.6 работают с ней через restorePartitionedDatabase из production ux-identity186: archive decode → known-parent preparation → one transactional psql. Production database/env не копируются и не восстанавливаются. Архивы/SQL остаются внутри временного контейнера, только публичный JSON сохранён в Git.
4 принятых случая: старый schema archive возвращает отсутствие native_counter_identity; последующий bootstrap добавляет0012 с NULL identities и прежними flags13/counters0,1024 без догадки; новый archive возвращает identity и markers45/61/counters0,1024 после удаления собственных rows; partitioned parent/child restore и migration record0012 остаются корректными. Старый archive fixture сформирован исключительно в собственной базе удалением новой nullable колонки и0012 record: это совместимый pre-0012 shape, не реальный пользовательский backup. Positive native fields — контролируемые fixtures, не counter proof устройства.
| Архив | Схема результата |
|---|---|
| Pre-0012 fixture | old schema/data → restore → bootstrap0012 → identityNULL, flags unchanged |
| Native identity fixture | dump → собственные rows удалены → actual restore → exact identity/flags/counters |
PostgreSQL server/client18.6, Node22 from production image; отдельный test-client image на официальном postgres:18 собран с проверкой Node/pg_dump. Docker socket в контейнер не передавался. Script SHA256 совпал с локальными байтами. ESLint passed. OwnDB mm_accept_166_1791829512285/role/container удалены, независимая проверка catalog/container absence passed. Рабочие3 контейнера и их runtime186/183 не менялись, реальных серверных/network writes/messages0; отдельная приёмка PostgreSQL restore в полном API/RBAC/multi-writer сценарии этим коротким тестом не заявляется.
Следующий188 — временный состав измерений: текущая реализация сравнивает количество известной wave с количеством всех series за период. Проверить rename/delete/add interfaces и active sessions, чтобы старый ряд не делал текущий срез навсегда unknown, а новое измерение без baseline не превращалось в measured0. Историю сохранить; причины absent object/optional peer failures и multi-instance остаются явными ограничениями.12.5 открыта. Локальный коммит без push.
12.5.188 — состав временных измерений после изменения интерфейсов (2026-10-13)
Baseline/fixed: при удалении одного ряда прежний186 builder навсегда оставлял current unknown и sessions2, хотя последний complete native wave содержал1 интерфейс.188 даёт current known/sessions1 с теми же4096 accounted bytes. Теперь expected count определяется для каждой wave, если все её строки имеют declared continuity marker нового producer. Счётчик активных интерфейсов берётся из последней такой wave. Legacy без marker сохраняет консервативный общий count; отсутствие строки не объявляется нулём по догадке.
Новый интерфейс без предыдущего baseline присутствует в expected count, но не в known pair sum: current остаётся unknown до следующей пары. Rename оставляет отдельный baseline нового имени, byte gap не додумывается, обе подтверждённые исторические части сохраняются. Declared confirmed continuity с NULL/empty native identity не доверяется. Поиск latest wave не использует неограниченный spread массива timestamps.
| Сценарий | Результат |
|---|---|
| Delete/rename старого series | latest complete wave снова current; stale series не увеличивает current sessions |
| Новый interface с единственным counter | unknown sum, current active count включает интерфейс |
| Следующая confirmed pair с0delta | measured0 допустим |
Unit membership deletion/addition/baseline/zero/history и backend build passed. Own PG SQL:65 cases9counter+14history+10TCP SSE+13volume+19status/38880ms, без skip.3 новые GET detail cases: deletion и rename возвращают known current/history/correct active count; добавление одного baseline оставляет current unknown. Markers/native-identity strings этих cases — собственные controlled fixtures, не native device mutation. OwnDB mm_accept_166_1791830718064/role/container удалены и отсутствие проверено.
Source460/524/compiled1040 SHA256 parity; backend ux-membership188 healthy/imageIds, frontend ux-warning183 unchanged/no rebuild. Only backend.env tag, rollback ux-identity186, migration0/secret env copy0. Actual API/browser1440/320 current/live/receipt/no errors/overflow passed. Реальные interfaces/пароли не менялись, messages0; rename/delete проверены собственным SQL dataset, не выданы за native VPN tunnel test.
Следующий189 — collector после отключения/смены источника между /interface и optional peer request: source.enabled/updatedAt должны проверяться перед каждой следующей командой и перед публикацией успешной записи. Live SSE уже проверяет каждую команду179. Затем проверить temporal peaks/частичные bins отдельно; этот блок не принимает sum-of-individual-peaks за общий одновременный пик.12.5 открыта. Локальный коммит без push.
12.5.189 — прекращение фонового опроса при изменении источника (2026-10-13)
Collector теперь повторно читает enabled/updatedAt по ID перед /interface, после его ответа до cache, перед /wireguard/peers, перед INSERT samples и перед успешной receipt. Выключенный/удалённый/изменённый источник прекращает цикл с явной причиной. Форма source check одинакова для всех типов серверов, Home exception отсутствует. Уже отправленный native request невозможно отменить задним числом; guard препятствует следующему request и публикации известного устаревшего результата. Межпроцессная атомарность source edit/native call/DB commit не заявляется.
Owned PG SQL:67 cases9counter+14history+10TCP SSE+13volume+21status/39536ms, no skip.2 новые cases обновляют own server.enabled/config внутри первого loopback HTTP handler до его ответа: snapshot.ok=false, peer request count не растёт, samples count не меняется. Сервер re-enabled только в own fixture для следующего case. Actual-collector VM граница стала поддерживать limit() read, unit и backend build passed. OwnDB mm_accept_166_1791831842508/role/container удалены, absence verified.
| Событие | Схема |
|---|---|
| Source выключен/config changed во время first request | завершение in-flight read → guard → no peer request/cache/new rows/ok receipt |
| Source неизменён | read → verify → validated rows → verify before publication |
Source460/524/compiled1040 SHA256 parity passed. Backend ux-sourceguard189 healthy/imageIds, frontend ux-warning183 unchanged. Only backend.env tag, rollback ux-membership188; migration0/secret env copy0. Actual API/browser1440/320 passed current/live/receipt/no errors/overflow. Real CHR не отключались/не перенастраивались; passwords/messages changes0.
Следующий190 — пик не должен вычисляться из partial/unconfirmed aggregate wave. Разные времена индивидуальных пиков user bindings также требуют отдельной temporal aggregation, а сумма индивидуальных максимумов не является общим одновременным максимумом.12.5 и внешние dependencies остаются открыты. Локальный коммит без push.
12.5.190 — пик только по подтверждённым волнам периода (2026-10-13)
Builder раньше брал максимум всех numeric points, включая partial wave с неизвестным вкладом нового интерфейса и точки за пределами range. Теперь RX/TX peak учитывает только свой observed flag, полный expected count соответствующей wave и timestamp внутри выбранного периода. Known bytes остаются учтёнными даже когда общий мгновенный срез неполон: это отдельные достоверные counter deltas, а не known whole-wave sum.
Unit проверил partial high point → последующая complete0 wave: current известен, observed peak0,1MiB volume сохранён. Future point вне range не повышает peak. Own PG:68 cases9counter+14history+10TCP SSE+14volume+21status/38553ms, no skip.1 новый actual GET case с known native identity fixtures проверяет exact0 peak/current, history и сохранение1MiB после partial high wave. Own namespace/role/container removed и отсутствие проверено.
Source460/524/compiled1040 SHA256 parity; backend build passed. Backend ux-peak190 healthy/imageIds, frontend ux-warning183 unchanged/no rebuild. Only backend.env tag, rollback ux-sourceguard189; migration0/secret env copy0. Actual API/browser1440/320 passed actual live/receipt/no errors/overflow. RouterOS config/password/message changes0; никаких deliberate failures на реальных CHR не вводилось.
| Срез | Результат |
|---|---|
| Частичная high wave | не участвует в общем observed peak |
| Complete known0 wave | 0peak/current допустим, accumulated known bytes retained |
| Point вне range | не влияет на peak периода |
Следующий191 — mergeBuiltTraffic пока суммирует индивидуальные пики частей, которые могли происходить в разное время. Нужно воспроизвести async peaks и определить общий пик по подтверждённым временным срезам с явным unknown при отсутствии совместимого времени.190 не выдаётся за исправление этого отдельного случая. Полный billing/coverage, scale/multi-instance/external integrations и12.5 остаются открыты. Локальный коммит без push.
12.5.191 — общий пик нескольких привязок: baseline (2026-10-13)
Блок начат, реализация/приёмка не завершены. Read-only baseline воспроизводит A=100Mbps на первой wave и B=100Mbps на следующей. Каждый индивидуальный peak100; mergeBuiltTraffic возвращает200, но complete combined wave builder показывает100. Учтённые объёмы совпадают. Это дефект временной агрегации пика, не потеря byte counters. Данные/стенд не менялись, writes0/native commands0.
Точный следующий шаг: общий peak вычислять из подтверждённых совпадающих временных срезов, сохраняя исходные timestamp/confidence внутренних parts; не складывать индивидуальные maxima. При отсутствии совместимого времени показывать неизвестное значение, сохраняя volumes/history/current metadata. Проверить разные времена peaks, совпадающий peak, missing contributor, jitter/неполные bins и recovery. Не подменять raw point peak максимумом bucket average без явной семантики. Нужны meaningful own SQL/API/UI cases перед production rollout.
Стенд остаётся backend ux-peak190/frontend ux-warning183. Source/runtime190 и real CHR/config/passwords unchanged; messages0. После191 — scoped control затронутых разделов и одна согласованная общая регрессия; внешние Portal/Telegram/client OS/multi-WAN/scale требуют доступов/сценариев из матрицы.12.5 открыта. Локальный commit без push сохраняет точное продолжение.
12.5.191 — подтверждённый общий пик привязок: реализация и приёмка (2026-10-13)
Исправлен baseline ниже: индивидуальные максимумы в разные моменты больше не складываются. A=100Mbps на первой волне и B=100Mbps на следующей дают общий пик100, совпадающие интервалы —200. Сумма byte deltas/учтённый объём сохранена. Пик является максимумом подтверждённых средних скоростей соседних счётчиков за совпадающие интервалы, а не мгновенным максимумом линии или максимумом chart bucket average.
Исходные интервалы и confidence parts хранятся во внутреннем WeakMap и не попадают в DTO/JSON. Merge, включая вложенный, требует совпадения начала и конца интервала и подтверждённых вкладов всех выбранных привязок для каждого направления. Jitter, отсутствие part, несовместимые интервалы или сериализованные parts без исходных точек не доказывают общий пик: observations.rxPeak/txPeak=false, UI показывает «—», а не ложный ноль. Подтверждённый ноль остаётся0. Для старого backend новый reader сохраняет прежнюю совместимость при отсутствии новых optional flags; interop проверен до переключения backend. История, объём и freshness metadata сохраняются. Данные разных серверов не интерполируются и не сдвигаются ради создания искусственного общего пика.
Изменены traffic-rate.ts, lib/traffic-observations.ts и профильные тесты. ReUI PRO/base-nova/Frame/KpiStatGrid переиспользуются, vendor/theme/layout не менялись. Проверены different/coincident peaks, nested merge, measured zero, missing/empty/legacy parts, jitter внутри одинаковых chart bins, одинаковый конец с разным началом и recovery. Реальный PostgreSQL/API fixture добавляет3 сценария пользователя с двумя привязками, включая неизменный объём750000000bytes. Все71 профильных SQL-проверок прошли41228ms без postgres-unavailable skip; собственные временная БД, роль и контейнер удалены.
Backend build и frontend TypeScript passed. Все77 уникальных E2E трафика прошли1.6m; начальные4 focused cases22.4s входят в77 и повторно не считаются. Production backend/frontend build passed; source manifests совпали461 backend+524 frontend файлов,1040 compiled backend artifacts совпали. Runtime backend/frontend ux-peak191, PostgreSQL healthy; frontend healthcheck отсутствует, работа подтверждена HTTP/browser. До backend rollout новый frontend принят с backend190. Actual API200 и fresh measurements обоих CHR, live UI1440/320 без page errors/overflow. Native конфигурация/пароли не менялись, messages0.
Протоколы: SQL, source, compiled, runtime, API, E2E, interop, live UI.
| Референс | Схема |
|---|---|
| ReUI Stats12 | Совпадающие интервалы всех привязок → подтверждённая сумма → максимум периода; нет совпадения → «—», объём сохранён |
Следующий192: одна согласованная общая backend-регрессия; фиксировать реальные skipped/external ветки отдельно. Последующий объём определяется результатом этой проверки и матрицей внешней приёмки. Portal/Telegram/client OS/multi-WAN/scale не приняты по fixture-тестам.12.5 открыта.
12.5.193 — трафик пользователей: одно чтение истории общего сервера (2026-10-13)
Устранены повторные одновременные SELECT истории при Promise.all пользователей. Cache раньше заполнялся только после await, поэтому100 пользователей с общим сервером успевали начать100 независимых чтений. Теперь Promise сохраняется перед await, потребители используют одну выборку этого сервера в рамках текущего запроса. Cache не сохраняется между запросами/периодами; другой serverId читает собственные данные. Ошибка распространяется как прежде, следующий запрос выполняет новое чтение и восстанавливается. Это не глобальный cache и не обещание транзакционно согласованного snapshot всех серверов/каталога.
Изменён traffic-users.ts, добавлен traffic-users-cache.test.ts в профиль traffic-rate. Проверка выполняет actual function body из исходника с подменой DB boundaries:100 concurrent consumers →1 server history read, unchanged1024bytes/user, новый запрос →новое чтение, другая serverId →отдельная выборка, failure/recovery. Это подтверждение call count алгоритма, не production SQL benchmark. Реальный профиль PostgreSQL/API прошёл все71 SQL cases41959ms без unavailable skip, включая100 bindings/user, volume/temporal peak/source/freshness. Собственные DB/role/container удалены.
Backend build passed. Production backend ux-peak193/version1.0.0-test.peak193 развёрнут, frontend ux-peak191 сохранён.462 backend source files и1040 compiled artifacts совпали. Frontend не пересобирался; его источник/production bundle остаются подтверждёнными191. Backend/PG healthy, frontend HTTP/browser passed. Actual API200 и current measurements обоих CHR, live UI1440/320 без page errors/overflow. Native конфигурация и пароли не менялись, messages0.
Протоколы: cache, SQL, source, compiled, runtime, API, live UI.
Общая регрессия192 начата на backend191; её24 backend профиля passed, текущий cache193 отдельно принят полным traffic-rate профилем. Не повторять общие неизменённые разделы. Полный браузерный прогон1286 ещё выполняется — не считать его завершённым. Исправлена ссылка live UI191: его evidence теперь хранится отдельно от исторического190, исходный протокол190 восстановлен. Следующий шаг — завершить192, разобрать ошибки полного E2E и восстановить только снимки текущего тестового запуска с сохранением8 исходно изменённых пользовательских PNG. Затем multi-instance/scale и внешние группы матрицы.12.5 открыта.
12.5.194 — трафик: координация опроса разных backend-процессов (2026-10-13)
На независимых Node-процессах подтверждён baseline: локальный collecting не препятствовал двум одновременным опросам одного источника и двум записанным волнам общей БД. Проверка использует собственную временную PostgreSQL БД и HTTP-эмулятор RouterOS на127.0.0.1, реальные CHR не менялись. Baseline.
Добавлена nonblocking session advisory lock8723105 на весь collectTrafficOnce в пределах общей PostgreSQL БД. Второй процесс возвращает существующий skipped snapshot до чтения настроек/истории, native GET и записи samples/receipt. Manual API уже преобразует skipped в409 «Сбор трафика уже выполняется», существующая семантика scheduler сохранена. Отложенная очередь опросов не создаётся. Локальный collecting сохранён для быстрых повторов внутри процесса. Неопределённый ответ acquisition не запускает run, соединение уничтожается; unconfirmed/failed unlock тоже уничтожает соединение вместо возврата в pool. Ошибка получения блокировки возвращает fatal snapshot без ложного успешного сбора.
Изменены traffic-collector.ts, добавлен traffic-collection-lock.ts и профильные unit/owned SQL tests. Actual collector body test обновлён под wrapper, не заменён копией алгоритма. Проверены busy/no work, malformed acquisition, run error, unlock false/error и destroy. Два настоящих процесса: первый удерживает HTTP-чтение, второй завершается skipped без второго запроса и samples; после первого следующий процесс выполняет новый опрос — lock released/recovery. SQL profile принял все71 ранее определённых cases и дополнительную cross-process sequence53237ms без unavailable skip; не считать её произвольным количеством новых тестов. DB/role/test container удалены. Production backend build passed;465 source files и1044 compiled artifacts совпали.
Backend ux-peak194/version1.0.0-test.peak194 развёрнут, frontend ux-peak191 сохранён. Backend/PG healthy, frontend HTTP/browser passed. API200, current measurements обоих CHR, live UI1440/320 без page errors/overflow. Native конфигурация/пароли не менялись, messages0.
Протоколы: SQL, source, compiled, runtime, API, live UI.
Границы: принято отсутствие параллельного traffic run при двух исправных process/session в одной БД, не координация всех writers приложения. Физическая потеря lock connection во время native GET/записи других pool connections не проверена; session lock не является fencing token. Не считать этот блок полной multi-instance/restore-drain/failover приёмкой. Следующий шаг — закончить и разобрать общую E2E192; затем отдельные multi-instance failures и внешние зависимости матрицы.12.5 открыта.
12.5.192 — общая регрессия после накопленных изменений (2026-10-13)
Завершена одна согласованная общая проверка:24 профиля backend из test:all прошли321237ms на собственной временной PostgreSQL БД с ограниченной ролью. Набор выполнялся на источнике191; backend193 request cache и194 collection lock после этого отдельно приняты актуальными полными traffic-rate SQL-профилями, build/source/compiled/API/live UI. Общие неизменённые разделы повторно не запускались. Протокол не приравнивает количество profiles к числу assertions или native операций.
В исходном общем прогоне были3 реальные skip-сообщения: Monthly SQL, IPv6 UDP/worker/SQL и replay сохранённого CHR Ping payload. Они проверены отдельно: Monthly на собственной БД mm_accept_149_* подтвердил5 точных месячных интервалов, leap-year и exclusion outside rows; IPv6 на собственной mm_accept_144_* прошёл через собранный production worker с UDP/SQL/minute-hour-day totals и shutdown; Ping replay использовал сохранённый публичный payload без новых команд CHR. Первая IPv6 попытка на TypeScript worker harness не загрузила src/db/index.js; это ошибка запуска harness, исправлена запуском того же теста в JavaScript с реальным compiled worker. Не скрывать исходный отказ и не выдавать loopback UDP за public IPv6 WAN. DB/roles/containers всех проверок удалены, production DSN не копировался.
Frontend:59 lib test files прошли с одной исправленной устаревшей проверкой dashboard-readers.test.ts. Ранее тест запрещал series:[null]; актуальная модель Ping намеренно допускает пропуски и переводит legacy measurements в unknown. Исправлен только тест: unknown/null проверен положительно, отрицательная/NaN series остаются rejected. Повторно прошли2 reader tests и4 соседних probe tests; runtime source/семантика не менялись. Scoped ESLint passed.
Общий настроенный браузерный набор:1286 уникальных сценариев в217 файлах passed1936347ms (32.3min), unexpected0/skipped0/flaky0. Включены77 сценариев трафика; их повторные focused/full runs не прибавляются к1286. Настроенные testIgnore context suites и внешние native сценарии в эту цифру не входят. Промежуточный сигнал ошибки по форматированному выводу не подтвердился: итоговый JSON содержит0 unexpected.125 исходно чистых отслеживаемых screenshots, перезаписанных тестами, восстановлены;8 исходно изменённых пользовательских PNG сохранены отдельно и восстановлены с проверкой SHA256. Пользовательские skills/AGENTS/config не включались в commits.
Протоколы: backend profiles, monthly SQL, IPv6 pipeline, Ping replay, frontend units, E2E.
Актуальный стенд backend194/frontend191, backend/PG healthy; production API и live UI приняты в194. Debian161.104.46.222 имеет только loopback/link-local IPv6, public IPv6/default IPv6 route отсутствуют по read-only проверке. Настоящие Portal SSO/Telegram/client OS/independent WAN/scale и полный distributed writer/restore drain не закрыты общей fixture-регрессией. Следующий195 — отдельная bounded failure/recovery проверка межпроцессного опроса; внешние группы требуют соответствующих стендов/параметров.12.5 остаётся открытой.
12.5.195 — реальный Portal1.3.1 и доставка Telegram (2026-10-13)
По прямому поручению пользователя установлен предоставленный auth-portal1.3.1 на том же Debian-стенде. Исходник прочитан из git.shx.one/denozord/auth-portal, точный tagv1.3.1=2e947b5a31d7bd6c17aff8dba3917fabf6640b91; опубликованный образ закреплён digestsha256:2bdf42400a1b35caa43303b9d01078b054b2a9041eba7019c1fffde71b7e4489. Byte/compiled совпадение образа с исходником не заявлено. Отдельная SQLite/data и bootstrap admin, случайные собственные admin password/HS256 secret, JWT lifetime900s, issuer/portal http://localhost:5175, allowlist только localhost/127.0.0.1:3000. Portal доступен через loopback/SSH, не публичный порт. Исходный .env приложения не копировался и не переписывался: новая закрытая compose.override.yaml задаёт только Portal и AUTH_* overrides. Portal/backend/PG healthy, frontend running. Backend194/frontend191 сохранены, source build не требовался для настройки.
Настоящий login API выдал Portal JWT с appmm и ожидаемым issuer. Приложение работает с AUTH_REQUIRED=true: без JWT401, реальный admin200, читатель mm:servers:read GET200/валидный create POST403, пользователь без appmm GET/POST403, повреждённая подпись401. Настоящий browser без API mocks прошёл MM→Portal login→callback→dashboard→servers; токен записан в storage, fragment удалён, page errors0. Начальные UI-harness ожидания h1«Обзор/Серверы» не соответствовали существующему PageHeader с breadcrumbs; тест исправлен под реальные route/button, UI source не менялся. Два основных own пользователя и оставшиеся fixtures первых попыток удалены через Portal API; bootstrap admin сохранён для доступа к стенду.
Отзыв проверен с явной границей: revoke-all отменяет refresh sessions, disabled user не логинится/Portal me401. Уже выданный access JWT MikrotikManager продолжает принимать200 доexp, поскольку backend проверяет подпись/issuer/exp offline и не проверяет состояние пользователя в Portal. Это не мгновенное глобальное revoke. Реальное истечение900s, passkey/OIDC и физические client OS в этом блоке не приняты.
По предоставленным тестовым bot/chat_id сохранены параметры через штатный API под настоящим Portal JWT. До настройки groups/rules0/outbox0: старых сообщений для рассылки нет. Первая send попытка получила502/unknown: с Debian недоступен TCP443 на DNS endpoint149.154.166.110; getMe и curl подтвердили connection timeout. Проверенный TLS endpoint149.154.167.220 того же api.telegram.org доступен. Для backend добавлен временный lab-only extra_hosts; TLS verification не отключался, произвольный proxy/mirror не использовался. После getMe200 (botId совпал) одна контролируемая send через штатный API принята. Всего2 send requests: initial unknown и verified transport control; не утверждать, что неизвестная отправка доказанно не состоялась. Пользователь подтвердил получение текста «MikroTik Manager — тест оповещений (Telegram).». Токен находится в закрытой конфигурации/БД стенда, в Git/публичные отчёты не включён. Автоматические rule/recovery/outbox/retry delivery ещё отдельная приёмка.
Протоколы: runtime, actual JWT/RBAC/revoke, real browser SSO, Telegram + human receipt. Данные входа bootstrap admin — локальный gitignored tmp/portal195-login.txt и закрытый файл стенда; секреты не публиковать в журнале.
Найден следующий196: настоящее reader JWT получает plaintext password CHR через GETservers. Подтверждён только boolean совпадения, секрет не выведен. Также authPortalBaseUrl для ссылки AppsMenu использует NEXT_PUBLIC_AUTH_PORTAL_URL сборки вместо текущего runtime Portal URL; hook switcher fetch уже использует runtime. Исправить оба API/UI недостатка, проверить reader/writer/admin и реальный Portal на ПК/телефоне, собрать/развернуть и создать локальный commit. Это ограничивает принятие приватности/навигации, но не отменяет доказанный базовый SSO/Telegram transport.
Пользователь подтвердил отсутствие public IPv6 на всех его стендах — внешняя IPv6 outer приёмка сейчас недоступна. Проверку crash/lock-connection loss из прежнего следующего195 перенести после Portal/Telegram.12.5 открыта.
12.5.196 — приватность серверов и согласованный runtime Portal (2026-10-13)
Реальное reader JWT в195 подтверждённо получало plaintext password CHR. Теперь serverReadForUser на HTTP list/detail возвращает password="" для пользователя без mm:servers:write/admin. Writer/admin и прежний AUTH_REQUIRED=false сохраняют existing DTO для редактирования. is_admin сам по себе не заменяет permission. Проекция создаёт копию и не меняет repository rows, хранимые/native credentials или работу collectors. Изменены servers-mapper.ts и два GET handlers routes/servers.ts; внутренние get/listServersRead остаются пригодными для native операций. Это защита этих endpoints, не аудит всех экспортов/secret-bearing DTO проекта.
authPortalBaseUrl теперь предпочитает runtime config, как существующий hook switcher fetch. Ссылка «Настроить на портале» больше не ведёт к build-time auth.shnt.top при отдельном тестовом issuer. ReUI PRO/base-nova/Frame/AppsMenu переиспользованы, vendor/стили/разметка не менялись. Unit подтвердил build fallback/runtime override/trailing slash.
Owned SQL test выполняет actual buildApp/auth middleware/handlers с подписанными test JWT на отдельной ограниченной роли: reader/writer/admin ×list/detail,401 безtoken, password вБД unchanged. Passed10996ms, own DB/role/container удалены. Новый test:server-privacy включён вtest:all, обычный прогон без явной own DB честно skip. Source TypeScript/backend build/scoped ESLint passed.41 unique E2E (runtime links2,header4,servers35) passed1.4m. Изолированные JWT не выдаются за реальный Portal: он проверен отдельно.
Production backend/frontend ux-peak196 развёрнуты.466 backend+525 frontend source files и1044 compiled backend artifacts совпали. Portal1.3.1/SQLite/shared lab secret и AUTH_REQUIRED=true сохранены новой закрытой Compose override; оригинальные credentials/.env не копировались. Реальный Portal admin API сохраняет необходимые поля редактирования, реальный reader list/detail не содержитпароль, валидная попытка создания403.4 live UI (reader/admin1440/320) безmocks/page errors/overflow: readonly control disabled, admin enabled, runtime Portal link http://localhost:5175/admin/apps. Собственные Portal users удалены. CHR config/passwords не менялись, новых Telegram send в196 нет.
Протоколы: SQL, source, compiled, runtime, fixture E2E, actual Portal API, live UI4.
| Референс | Схема |
|---|---|
| ReUI App Shell12 | Runtime issuer/Portal → меню приложений → тот же Portal; reader → masked DTO + blocked edit, writer → existing editor |
Следующий197: реальная доставка из outbox через собственную временную БД, dedupe/two senders, controlled lost receipt после реального Telegram acceptance, no automatic repeat, explicit acknowledged retry/stale version/RBAC. Планируется3 помеченных test messages, включая намеренный повтор№2; не превращать controlled receipt suppression в физическую WAN/lost-ACK приёмку. Portal JWT revocation доexp, настоящее expiry/refresh/client OS и crash/lock-loss остаются отдельными границами.12.5 открыта.
12.5.197 — доставка Telegram и управляемый повтор (2026-10-13)
Production compiled outbox проверен в собственной временной PostgreSQL БД и ограниченной роли, с реальными JWT Portal и тестовым Telegram bot/chat. Первый live прогон: enqueue с одинаковым dedupeKey сохранил одну запись; два независимых Node sender процесса выполнили одну отправку, одна запись sent и одна history. Telegram принял№2, затем драйвер намеренно подавил ответ: статус unknown, следующая автоматическая диспетчеризация не отправила сообщение повторно. Это контролируемая имитация потерянного ответа, не физический обрыв WAN.
Reader retry403, отсутствие acknowledgedDuplicateRisk400, admin expectedVersion0→1 с подтверждением риска200, повтор старой версии409. Однако завершающий assert первого полного live прогона sent=1 не прошёл; outcome тогда не был записан. Причина не установлена. Исходный failed протокол сохранён, цельный непрерывный live сценарий не объявляется пройденным. Для локализации полный сценарий с реальной БД/Portal JWT и симулированным Telegram ответом прошёл без сетевых отправок. Далее только оставшаяся ручная отправка проверена на новой собственной unknown fixture: Telegram accepted, status sent, resolutionVersion1, history одна. Это отдельный успешный live тест, не продолжение прежней БД.
Всего реально приняты3 сообщения: одно TEST197№1 и два одинаковых TEST197№2, последние являются намеренным повтором. Пользователь подтвердил именно это количество. Три own DB/role/container и собственные Portal reader users удалены; временный private bot file на сервере удалён. Рабочие настройки Telegram приложения сохранены для следующих пользовательских проверок. Пароли/конфигурация CHR не менялись, runtime остаётся ux-peak196. Драйвер не входит вtest:all, требует own DB, явный чат и подтверждение риска, имеет отдельный resume режим. Диагностика завершающей отправки теперь сохраняет outcome/статус; отрицательный provider response не превращается assert в искусственный unknown, счётчик учитывает начало request.
Протоколы: первый partial/failed live, полный SQL с simulated provider, отдельный live retry, итог и ограничения.
Следующий198: настоящий expiry/logout/reissue Portal и безопасный return_to. Первый непрерывный Telegram live сценарий остаётся диагностической границей; повторять его только при достаточной диагностике и основании, а не отправлять дополнительные дубли ради зелёного счётчика.12.5 открыта.
12.5.198 — срок действия Portal JWT, права и выход (2026-10-13)
Использован настоящий JWT, выданный Portal в195 и естественно истёкший к проверке: MM GET servers401, Portal me401 и reissue401. Токен не редактировался и TTL не менялся. На собственном временном reader через документированный PUT /api/v1/admin/users/:id/access удалён доступmm: прежний JWT по-прежнему200 доexp, reissue200 выдаёт текущие claims и новый MM JWT403. Возвращённый доступ и новый reissue восстановили200. Первый неверно адресованный PATCH в диагностическом драйвере был исправлен на PUT/access; изменение source продукта не требовалось. User fixture удалён204.
Logout200 очищает refresh cookie(Max-Age0), но ранее выданный bearer MM JWT остаётся200 и Portal reissue с ним также200 доexp. Это подтверждённая граница offlineJWT и Portal1.3.1: cookie/session logout не означает немедленный отзыв access token. Свежие JWT/credentials в Git не сохранялись.
Live UI1440/320 с настоящим expired JWT: MM очистил mmapp_token, направил на Portal, реальный login/callback восстановил приложение, fragment удалён, overflow/page errors нет. Однако callback открыл /dashboard вместо исходного /servers: контекст не сохранён, следующий199 исправляет это. Внешний https://outside.invalid/auth/callback не вызвал попытки навигации после login; Portal остался на /admin. Browser /logout очистил token storage и показал login. Защитный browser route только блокировал возможную недоверенную навигацию, ответы API не подменял.
Оставшиеся return_to на другой localhost port и похожий hostname не приняты: серия диагностических входов достигла rate limit Portal. HTTP GET / и /api/v1/auth/config подтвердили429 с Retry-After18/17s; это не объявлено ошибкой защиты return_to. Промежуточные успехи сохранены отдельно, полный UI прогон не claimed. Повторять только эти оставшиеся случаи после cooldown, без нового полного цикла. Source/runtime/ReUI не менялись.
Протоколы: actual lifecycle API, live UI и границы429.
Следующий199: восстановить исходный same-origin раздел и query после SSO с проверкой permissions и запретом внешних/auth callback redirect. Затем профильные E2E/deploy и два оставшихся Portal return_to.12.5 открыта.
12.5.199 — восстановление раздела и параметров после SSO (2026-10-13)
Из198 подтверждено: expired session на /servers попадала после login в /dashboard. redirectToPortalLogin теперь добавляет исходный pathname+query в next callback URL. AuthCallbackPage после valid claims выбирает permittedAuthReturnPath и проверяет существующее permissionForPath/can; недопустимый путь или недостаточные права используют firstAllowedPath. При повторном handoff next сохраняется. JWT fragment не включается в сохранённый путь.
Новый pure helper отклоняет внешние/protocol-relative URL, backslash/control/space, слишком длинный путь, auth/api/access-denied loop, нормализованный dot traversal вauth и percent-encoded pathname. Query, включая percent-encoded filter values, сохраняется; hash удаляется. Консервативное ограничение касается pathname: приложение использует обычные фиксированные пути/ID; percent-encoded pathname не восстанавливается, выбирается fallback. Это не расширение существующей карты permissions и не замена backend RBAC.
Unit unsafe/normalization/query/permissions passed, frontend TypeScript и scoped ESLint passed.12 unique E2E/24971ms/0unexpected:10 query/denied/external/auth-loop/handoff cases1440/320 и2 runtime Portal links. Это fixtures, не реальные подписи Portal. Отдельно production frontend ux-portal199 собран и развёрнут,527 source files совпали перед build. Backend ux-peak196/Portal1.3.1/AUTH_REQUIRED=true сохранены.2 live UI с настоящим naturally expired JWT и login Portal1440/320 восстановили /servers?server=42&tab=details, fragment удалён, errors/overflow нет. CHR/native config и backend не менялись, новых Telegram sends нет.
Оставшиеся return_to198 проверены адресно: http://localhost:3001/auth/callback и http://localhost.evil.invalid:3000/auth/callback не вызывают external navigation, Portal остаётся /admin. Browser logout очищает storage. Предыдущий lookalike URL в драйвере был синтаксически ошибочным (порт3000.evil.invalid), поэтому login form отсутствовала; это исправлено в тесте. Подтверждённый429198 сохраняется в историческом протоколе, но не объявляется причиной этого отдельного malformed-URL сбоя. Повторные full cycles прекращены; реальные endpoints не mock. Доверенные allowlist origins сохранены.
Протоколы: E2E12, deployment, actual expired recovery2, remaining return_to.
| Референс | Схема |
|---|---|
| ReUI App Shell12 | Раздел + фильтры → expired session → Portal → callback с проверкой прав → тот же раздел + фильтры |
Следующий200: owned PostgreSQL/child-process crash и advisory-lock loss traffic collector. Цельный непрерывный Telegram live197 остаётся отдельно с исходным failed evidence; успешные chunk tests не отменяют его. Logout не отозвал offlineJWT доexp, publicIPv6/clientOS/independentWAN/scale остаются внешними ограничениями.12.5 открыта.
12.5.200 — восстановление коллектора после падения и потери блокировки (2026-10-13)
В отдельной own DB/ограниченной роли на Linux два сценария действительного сбоя: SIGKILL дочернего коллектора при удержанном ответе локального RouterOS fixture и pg_terminate_backend только собственного lock PID, выбранного по точным datname/usename/key8723105. Production PID/CHR не затрагивались. Старый production compiled ux-peak196 воспроизвёл Unhandled error event и nonzero exit при потере session-lock connection. После SIGKILL PostgreSQL освободил advisory lock, новый процесс собрал первую волну. Baseline не выдаётся за passed исправление.
withTrafficCollectionLock теперь слушает error/end dedicated client, фиксирует потерю соединения, уничтожает его и снимает listeners. Callback получает assertActive, helper проверяет его также после callback. collectTrafficRun проверяет active guard перед проходом/источником, после чтения source-state, перед итоговыми writes и в catch ветках; известная потеря lock больше не приводит к записи error/settings старого прохода. collectTrafficOnce возвращает fatal snapshot, collecting сбрасывается finally. Unit подтвердил error/end без unhandled event, guard abort, destroy/listener cleanup; прежние busy/acquire/unlock cases сохранились.
Production compiled ux-lock200 на own DB: SIGKILL recovery passed; lock connection terminated во время held native response — процесс survived, fatal snapshot, ноль новых traffic_samples, last_collected_at не переписан. Следующий независимый процесс успешно собрал новую волну.3 own DB/role/container (baseline/fixed/profile) удалены и отсутствие проверено.71 профильная SQL case + cross-process skip/release/recovery passed57603ms, TypeScript build и scoped ESLint passed. Перед build468 source files совпали,1044 compiled artifacts matched. Backend ux-lock200 healthy развёрнут, frontend ux-portal199/Portal/AUTH_REQUIRED сохранены.3 real API200 и live UI1440/320 — provenance/received live labels, noerrors/overflow. Native CHR config/passwords не менялись.
Граница: active guard реагирует на наблюдённые error/end; это не fencing token и не атомарная защита всех writes на других pool connections. Окно между проверкой и write, задержка TCP detection и физическая network partition остаются ограничениями. Уже отправленный native HTTP GET не отменяется; tested response fixture лишь удерживал ответ. Не объявлять гарантию exactly-once при произвольном разрыве.
Протоколы: baseline, fixed lifecycle, SQL profile, compiled, deployment/bounds, live traffic.
Следующий201: цельный Telegram live197 с диагностикой начала requests/response codes/dispatch outcome/status и ограничением3 сообщений в собственном чате. Controlled lost receipt остаётся имитацией; первоначальный failed evidence не удалять.12.5 открыта.
12.5.201 — цельный живой сценарий очереди Telegram (2026-10-13)
Обновлён acceptance driver: ограниченный TEST label, request-start counters, safe HTTP status/accepted trace, dispatch outcome и финальная строка очереди; Telegram send pacing1500ms, отрицательные ответы provider не искажаются assertion в unknown. Драйвер не входит вtest:all, явный own DB/chat/duplicate-risk ACK обязательны, число live sends ограничено3 (resume1). Изменение только приёмочного инструмента; продуктовая очередь не менялась.
Actual production compiled backend ux-lock200, ограниченная PostgreSQL own роль и real Portal JWT. В одном непрерывном прогоне/одной БД: duplicate dedupeKey → одна запись; два независимых sender процесса → один provider send и одна sent/history. Telegram accepted№2, receipt intentionally suppressed → unknown; повторная автоматическая диспетчеризация не отправляет. Reader retry403, missing acknowledgement400, admin version0→1 pending200, stale retry409. После подтверждённого ручного retry Telegram accepted, sent1/failed0/held0, итог две sent строки/две history. Provider принял три сообщения TEST201(IDs6/7/8); пользователь подтвердил одно№1 и два№2.
Own DB/role/container и Portal reader user удалены, отдельный private bot file удалён; рабочие настройки приложения сохранены. Нативные CHR и runtime images не менялись, дополнительных отправок вне бюджета не было. Полный успешный201 теперь дополняет partial/failed197 и отдельный resume197; исходный failed evidence сохраняется. Точная причина первого сбоя197 не установлена: pacing/новая диагностика не выдаются за доказательство его причины или исправление продуктового дефекта. Controlled receipt loss не является физическим WAN timeout/доказательством exactly-once на стороне Telegram.
Протокол: цельный live тест и подтверждение пользователя. Следующий202 — reader API аудит секретов административных интеграций; широкие публичные IPv6/clientOS/independentWAN/scale/external jobs остаются в матрице.12.5 открыта.
12.5.202 — чтение административных интеграций без раскрытия секретов (2026-10-13)
На actual deployed ux-lock200 создан собственный Portal reader с mm:servers/alerts/backups/uptime/traffic:read, без writer/admin.10 real GET endpoints: servers, alerts, outbox, backup storage, uptime settings/speed probes, traffic flow settings, GeoIP200; EvoBGP settings/scheduler403. Для тех же10 endpoints безJWT401. Дополнительно server details200 с password пустым. Recursive response check не нашёл непустых password/botToken/token/apiKey/secretAccessKey/privateKey/licenseKey и известных CHR/bot test secrets. Значения credentials в evidence не сохранены.
Telegram в рабочем приложении действительно настроен и доставлял сообщения201: reader alerts DTO не содержит raw bot token. S3/EvoBGP secrets в текущем стенде не заполнены; их маскирование populated credentials не объявляется доказанным данным read-only прогоном. Source audit подтвердил DTO secretConfigured уbackup/EvoBGP, GeoIP только metadata, speedProbeRead безpassword. App config/credentials не менялись, native commands не запрашивались. Собственный reader удалён204. Вспомогательный драйвер сначала ошибся на JSON parsing пустого204cleanup; исправлен на nullable response body, actual removal уже произошёл; финальный прогон successful/cleaned.
Протокол: actual reader API. Это scoped DTO audit10 endpoints, не аудит binary backup/cert export или произвольных embedded credentials в errors. Следующий203: собственная ограниченная PostgreSQL DB с синтетическими заполненными S3/EvoBGP/Telegram secrets, actual compiled handlers/JWT, без send/network probe.12.5 открыта.
12.5.203 — маскирование заполненных секретов интеграций (2026-10-13)
Actual compiled buildApp/auth/GET handlers ux-lock200 проверены на собственной ограниченной PostgreSQL роли/БД с непустыми синтетическими S3 secret access key, EvoBGP API key и Telegram bot token. JWT подписаны штатным Fastify тестовым RAM-secret/issuer: это изолированные test JWT, не real Portal login (реальный reader был проверен202). startScheduler=false, global fetch запрещён и считает обращения.
9 проверок reader/admin/noJWT ×backup storage/EvoBGP settings/alerts: разрешённые DTO200 содержат secretConfigured/tokenConfigured=true, но не сохранённые секреты. Reader EvoBGP403, безJWT401. Хранимые значения всех3 секретов неизменны, externalRequests0. S3 provider local/EvoBGP disabled, реальных probe/send/job не выполнялось. Own DB/role/container удалены. Первый драйвер попытался импортировать dev-only jose из production image и не запустил cases; исправлен на штатный app.jwt.sign, никакой зависимости/продуктового кода не добавлялось. Оба временных окружения очищены. PostgreSQL выдал warning о concurrent query наclient в существующем repeatable-read alerts overview; это совместимо с текущим pg8, не объявлено pg9 acceptance.
Протокол: owned SQL masks9. Это scoped DTO proof, не S3 connectivity, EvoBGP execution, Telegram transport (принят201) или аудит всехexport/error text. Runtime не менялся. Следующий204: actual Portal reader/admin navigation основных разделов ПК/телефон после auth199, GET/overflow/page errors и отсутствие mutation requests.12.5 открыта.
12.5.204 — навигация основных разделов с реальными ролями (2026-10-13)
Actual Portal1.3.1 issued admin/own reader JWT, deployed frontend ux-portal199/backend ux-lock200.13 разделов: dashboard, servers, uptime, traffic, statistics, WireGuard, IPsec, GRE, VXLAN, BGP, OSPF, alerts, backups ×reader/admin×1440/320 =52 scoped live сценария. Перед проверкой каждого маршрута дождались HTTP200 его профильного API (dashboard использует servers read gate), а не только общего header/auth config. Сохранены успешные пути API и non200 ответов нет. Reader server Add disabled/admin enabled; fragment отсутствует, JavaScript errors0, overflow нет, mutation requests0.
Первый диагностический обход проверял любой shared GET200 и был недостаточен для подтверждения data fetch; финальный52 усилен specific endpoint ожиданием. Counts не складываются. API/Portal ответы не mock, JWT storage seed использует реально выданный token. Своя reader fixture удалена204. Tunnel/form actions не выполнялись и новые native объекты не создавались; обычные GET могут опрашивать RouterOS. Это проверка navigation/session/section API/адаптивности после общих auth changes, не полная приёмка каждой формы/native state или throughput.
Протокол: live navigation52. Source/runtime не менялись. Следующий205: scoped automated WCAG-tagged audit data sections(light/dark,ПК/телефон) на реальном приложении; не считать его полным WCAG сертификатом.12.5 открыта.
12.5.205 — контраст живых данных и предупреждения целей (2026-10-13)
Actual admin Portal JWT, без API mocks: traffic/alerts/backups ×light/dark×1440/320, axe-core4.11.3 tags WCAG2A/AA,2.1A/AA,2.2AA вmain-content иосновной навигации. Baseline выявил4 failing combinations: light traffic RX/TX2.07–3.76:1 иlight alerts warning4.32:1 при требовании4.5:1. Dark иbackup passed. Baseline сохранён, не переписан successful result.
В app traffic6 numeric spans RX/TX теперь используют semantic text-foreground; стрелки/графики/форматеры сохранены. AlertsTargetIssues переиспользует установленный ReUI Alert вместоlegacy UI Alert, предупреждениеvariant warning/role status исуществующее содержимое сохранены. Vendor/shared theme не менялись. API прочитан через ReUI MCP: docs, preview. Замечание axe ксерой кнопке «Обновить» перепроверено после actual enabled state: initial snapshot был вtransition загрузки. Стили кнопки не менялись, финальный тест ждёт завершения загрузки данных, ане исключает contrast rule.
TypeScript/scoped ESLint passed;25 unique E2E34060ms,0unexpected/skips (target warning +shell accessibility/keyboard/layers).4 clean shell screenshots восстановленыпослетеста,8 исходных dirty GRE/VXLAN скриншотов сохранены. Production build/source527 matched, frontend ux-accessibility205 развёрнут, backend ux-lock200/Portal/AUTH_REQUIRED сохранены. Повторный actual tagged audit12/12 безviolations, includinglight numbers/warning. Incomplete checks сохраняются вprotocol, не объявлены passed WCAG критериями. Это default visible admin states, не полный WCAG сертификат, manual keyboard audit всехforms или reader dialogs.
Протоколы: baseline, fixture E2E25, live audit12, deployment.
Следующий206: actual live keyboard/focus для общихmenus итиповых Dialog/Sheet, ПК/телефон/роли, безapply/native mutation.200 collector loss реагирует только наobserved errors/end (неfencing);201 whole Telegram accepted, initial197 cause unproven.12.5 остаётся открытой из-за остальныхграниц внешней матрицы.
12.5.206 — живая клавиатура и возврат фокуса (2026-10-13)
Actual Portal reader/admin JWT, deployed frontend ux-accessibility205/backend ux-lock200.6 сценариев ×1440/320×reader/admin =24: Tab skip-link→main-content; Enter/ArrowDown/Escape apps menu; Enter/Escape system monitor; keyboard server row menu иEscape возврат; reader Add disabled/admin server create Dialog; GRE history Sheet выбранного enabled CHR. Вdialog/sheet Tab проходит числоfocusable controls+3 иShift+Tab3, фокус остаётся внутри, Escape возвращает original trigger. Форму не заполняли/не применяли, config restore не нажимали, mutations0/page errors0/nooverflow; собственный Portal reader удалён204.
Первоначальная мгновенная проверка DOM containment после Tab иногда видела асинхронный focus transition Base UI; финальный тест ждёт стабильногоcontainment черезpoll. Product focus code не менялся. Это проверка listed states, не full keyboard/screen-reader certification всехформ. Source/runtime unchanged. Протокол: actual keyboard24.
В source review обнаружено: GRE caller не передаёт существующий restoreDisabled вобщий ConfigHistorySheet, defaultfalse. Backend write guard не отменяет необходимость корректного UI. Следующий207 — аудит всехcaller иread-only/disabled/device state запреты кнопки отката, профильныеfixtures иlive UI безapply.12.5 открыта.
12.5.207 — права отката общей истории конфигураций (2026-10-13)
Actual Portal reader настаром frontend ux-accessibility205 видел50 enabled restore buttons GRE; безнажатия подтверждёнbaseline.5 из6 ConfigHistorySheet caller не передавалиrestoreDisabled,defaultfalse. Теперь propобязателен, defaulttrue дляuntyped omission; GRE/WireGuard/IPsec/Filters/Firewall передаютpermission/device/busy guards. Recursive routes ужеимелиguard. Reader требуетnetwork:write (Filters filters:write), disabled/missing device запрещаетaction; GRE/IPsec/Firewall используютexisting readiness guards. Callbacks пятиcaller повторно проверяютpermission непосредственно передrequest. ШаблоныReUI/Timeline/Sheet/vendor unchanged; текст объясняет недоступностьотката.
Перваяширокая Filters readiness condition заблокировала прежнийдопустимыйretry послеapplied+failed read.3 regression failures обнаружены иисправлены: Filters используетpermission/enabled/operation guards, stale/failed read не добавляетновый запретrollback. Существующие правиласетевыхопераций сохранены.40 unique E2E(24 role/devicefixtures+16 existing restore/error/retry/lock),68987ms,0unexpected/skips. TypeScript/ESLint0errors;12 старыхunused import warnings Filters не менялись. Native apply толькоmocked tests, наCHR откатне выполнялся.
Production frontend ux-history207/source527 matched, backend ux-lock200/Portal/AUTH_REQUIRED сохранены.24 actual live UI6sections×reader/admin×1440/320 наpopulated historical metadata: readerbuttons disabled, adminenabled послеstable device read, informativecopy, nooverflow, Escape→trigger, mutationrequests0. Первыйadminrecursive check сделан доокончанияread ивиделcorrect temporarybusy; тестисправлен наожиданиеready, productguard неослаблялся. Own Portal users удалены204. Credentials/native configs не менялись.
Протоколы: live baseline, E2E40, live24, deployment. Следующий208: source GET WireGuard includePrivateKey флагне проверяетwrite permission; scoped nativekey privacy +read-only network workspaces.12.5 открыта.
12.5.208 — приватные ключи WireGuard и режим просмотра сетевых разделов (2026-10-13)
Старый production backend выдавал синтетический непустой приватный ключ reader при GET WireGuard с includePrivateKey=1/true. Baseline подтверждён actual compiled auth/mapper на собственной ограниченной PostgreSQL БД и локальном RouterOS HTTP fixture. Теперь явный запрос приватного ключа требует mm:network:write/admin, иначе403 до любых native requests. Обычный GET200 сохраняет public key и не содержит private key. is_admin без необходимого permission не заменяет право. Writer/admin сохраняют прежнее действие, legacy AUTH_REQUIRED=false не менялся.
WireGuard, IPsec, GRE, Firewall и Filters показывают режим просмотра и запрещают writer controls при read-only JWT. Использованы существующие readiness/mutation helpers; WireGuard toolbar/import/key-export/peer actions и callbacks дополнительно защищены. Backend RBAC остаётся авторитетной проверкой. Установленные ReUI primitives, vendor files и theme не менялись: добавлены operation-state props/copy.
11 fixed SQL cases: reader/writer/admin ×обычный GET/два private flags, is_admin alone, безJWT401; reader denied native request count0. Baseline/fixed/profile own DB/role/container удалены. WireGuard profile прошёл14.6s, включая56 node:test проверок; другие скрипты профиля не прибавляются к этому числу. Скопированный JSON label ошибочно называл traffic-rate, фактически runner запускал test:wireguard; label исправлен с сохранением originalReportedCommand. TypeScript/backend build/ESLint0errors,12 старых warnings Filters остаются.53 unique E2E:20 readonly PC/mobile +33 history/readiness/refresh. Два первоначальных GRE writer failures были некорректной fixture без обязательного ipsec:null; исправлены только данные теста,20 повторных cases прошли. Повторы не складываются.
Backend/frontend ux-native208 развёрнуты;470/527 source files и1044 compiled artifacts совпали, backend healthy. На каждом CHR через реальный admin API создан собственный WG-интерфейс с уникальным именем/свободным портом. Real reader обычный GET200 безключа, private flags403, admin получает ключ/public key сохранён. Private material вevidence не сохранялся.20 live UI5sections×reader/admin×1440/320 проверили создание/import/key-export controls, mutation requests0. Затем оба собственных интерфейса иPortal reader удалены; отсутствие интерфейсов проверено. Пароли и исходные native объекты не менялись. Это API privacy/UI proof, не WireGuard handshake/data-plane тест.
Протоколы: baseline, fixed SQL11, profile, E2E53, live UI20, native privacy/cleanup2, compiled, deployment.
Следующий209: GRE mapper содержит ipsecSecret иipsec.secret, проверить оба публичных GET иограничить выдачу секретов reader, сохранив crypto-state/public metadata иwriter editing.12.5 открыта.
12.5.209 — доступ к GRE PSK и достоверность каталога IPsec (2026-10-13)
В production baseline читатель получал PSK через GET /gre/tunnels. Каталог /filters/gre-tunnels ключ не раскрывал, но всегда возвращал ipsec:null, скрывая сам факт настройки IPsec. Основной GET теперь копирует публичный DTO и очищает secret при отсутствии mm:network:write/admin; алгоритмы и наличие объекта IPsec сохраняются. Internal snapshot и право редактирования для writer/admin не меняются. is_admin без permission не даёт доступ к ключу. Legacy AUTH_REQUIRED=false сохранён. Общий каталог Filters возвращает только признак IPsec и пустой secret для всех ролей.
Экспорт скрытого PSK явно помечен как шаблон, содержит <IPSEC_PSK> и указание заменить ключ перед применением. Пустой ipsec-secret не подставляется как готовая конфигурация. Установленные ReUI компоненты и тема не изменялись.
Проверки: baseline и исправленный production backend — по 12 уникальных SQL/API-кейсов на собственных ограниченных PostgreSQL DB/role, с синтетическим PSK и настоящим auth middleware. Snapshot сохраняет исходный PSK; native writes 0. Оба комплекта DB/role/container удалены. Локальный test:live-maps, frontend TypeScript, backend build и ESLint прошли. Четыре E2E: скрытый ключ/шаблон на 1440 и 320px, прежние изменение/очистка PSK writer. Полную регрессию 192 не повторяли.
Backend/frontend ux-gre209 развёрнуты; 473/527 source files и 1048 compiled artifacts совпали, backend healthy. Live: по одному собственному отключённому GRE с PSK на каждом CHR, реальные Portal admin/reader JWT; reader не получает ключ, admin сохраняет его, каталог обеих ролей показывает IPsec без ключа. Четыре UI-кейса reader/admin × 1440/320, без API mocks и без UI mutations. Оба интерфейса и временный Portal user удалены; отсутствие интерфейсов проверено. Пароли и исходные объекты не менялись. Это проверка privacy/configured state, не шифрованного data plane.
Первоначальная сборка имела неверную ссылку на базовый Docker image; исправлена до развёртывания. Финальный frontend собран с mock=false и live default. Два первых native create отказали: опущенный keepalive превращался в 0, который RouterOS отклоняет. Cleanup прошёл; проверка завершена с явным 10s,3. Ошибка значения по умолчанию остаётся отдельным пунктом 210. Повторные проверки не складываются в число уникальных кейсов.
Протоколы: baseline, fixed SQL/API, профиль, E2E, native/UI/cleanup, source, compiled, deployment.
Следующий блок 210: исправить создание GRE с опущенным keepalive, проверить фактический RouterOS ответ и прежнее редактирование. Этап 12.5 открыт; внешние ограничения в актуальной матрице сохраняются.
12.5.210 — GRE keepalive и совместимость публичного каталога (2026-10-13)
На обоих CHR собственные отключённые интерфейсы подтвердили: native REST отклоняет 0, none, пустую строку, disabled, no и ноль попыток. Дробные интервалы принимаются, но сокращаются RouterOS до целых секунд. Поэтому форма и write schema требуют целые значения 1..4294967295 вместо обещания «0 = откл.». Неверный ввод сохраняет форму и не отправляет запрос. Официальный default 10s,10: MikroTik GRE.
Опущенные параметры создания теперь дают 10s,10; один заданный параметр сохраняется, второй получает default. Основной GET и каталог Filters используют общий разбор native единиц/clock: 1m = 60с, 1m30s = 90с. PATCH без параметров keepalive сохраняет исходную строку snapshot, не преобразует таймер при изменении комментария/PSK. Legacy snapshots не переписаны; произвольные legacy/unknown timers и их экспорт не приняты этим блоком.
Аудит потребителей выявил несовместимость 209: shared schema Filters допускала только ipsec:null. Теперь она принимает {secret:""} или null, отвергает реальный ключ. Карта сохраняет configured IPsec; Filters и диагностика используют обновлённую схему. ReUI primitives и theme не менялись.
Проверки: 24 direct native syntax cases на отключённых собственных GRE, с очисткой; production SQL/API14 на собственной ограниченной DB/role, включая 8 invalid cases до native requests, четыре создания, сохранение native timer и чтение минут. SQL DB/role/container удалены. Профиль live-maps, schema unit, 5 network-map units, TypeScript/backend build/ESLint прошли. 13 уникальных E2E: GRE формы/PSK/валидация9 и Filters gateway/retry4. Копии fixtures имеют configured IPsec; прежние повторные действия сохранены.
Runtime ux-gre210: backend healthy, source475/527 и compiled1048 matched. На каждом CHR приложение создало отключённый GRE без keepalive и с явным allowFastPath=false для PSK; native default10s,10 подтверждён. После native 1m,3 GET показывает60с, PATCH комментария сохраняет1m,3, explicit0 даёт400 без изменения native. Два UI GRE и два UI Filters на1440/320 проверили форму, отсутствие запроса при invalid input и доступность собственного GRE с IPsec в каталоге шлюзов. Оба интерфейса удалены, отсутствие проверено. Пароли не менялись; это не data-plane test.
Два первых create с PSK и опущенным allowFastPath получили502: текущий API default FastPath несовместим с PSK. Это отдельное обнаруженное ограничение, не скрытое успешным повтором; дальнейшая проверка задала false явно. Следующий приоритет211 — подтверждённый обход auth через encoded API prefix. После него исправить FastPath/PSK default и экспорт недопустимого/неизвестного keepalive.
Протоколы: native syntax, дополнительный синтаксис, SQL/API14, профили, E2E13, native/UI/cleanup, source, compiled, deployment.
12.5.211 — JWT/RBAC для закодированных URL (2026-10-13)
Actual baseline: обычный /api/servers без JWT возвращал401, но /%61pi/servers возвращал200 и server rows с непустыми паролями. Fastify распознаёт encoded static segments; middleware сравнивал raw URL и пропускал auth для encoded /api prefix. Для encoded имени раздела можно было также получить fallback dashboard permission. В evidence сохранены только статусы, число строк и boolean наличия пароля; raw body, credentials и JWT не сохранялись и не выводились.
Общий preHandler и requireAuth теперь используют request.routeOptions.url — фактически выбранный Fastify маршрут. Проверка public auth config/health сохранена; percent decoding не выполняется повторно вручную. Permission mapping OSPF принимает доверенные parameter templates наряду с прежними numeric paths; HEAD получает те же read permissions, что GET. Политики ролей и AUTH_REQUIRED=false не расширены. Frontend и RouterOS конфигурация не менялись.
42 канонических auth fixtures: encoded static prefix/раздел, GET/HEAD/PATCH, denied handler count0, OSPF reader/preview и servers-only denial, public config/health. Прежние test:auth, GeoIP JWT и NetFlow private export guards прошли; backend build прошёл. Изменена общая auth-основа, поэтому добавлены профильные проверки разных ресурсов и параметризованных маршрутов; полный UI regression192 не повторялся для backend-only изменения.
Production compiled SQL/API29 на собственной ограниченной DB/role: anonymous401, dashboard-only403, network reader/writer GET и PSK redaction, denied PATCH403 до native, public config200. Native writes0; DB/role/container удалены. Backend ux-auth211 развёрнут healthy; source477 и compiled1048 совпали. Frontend ux-gre210 сохранён. Live26 с настоящими Portal JWT: анонимные GET/HEAD401, обычные/encoded server и GRE GET по ролям, пустой PATCH403. Пустое тело гарантирует отсутствие native apply даже при ошибке защиты. Два временных Portal user удалены; секреты не публиковались. Пароли CHR не менялись.
Протоколы: actual baseline, профиль, production SQL/API29, live26, source, compiled, deployment.
Следующий212: GRE create с PSK и опущенным FastPath, explicit incompatible combination, экспорт недопустимого/неизвестного keepalive. 12.5 остаётся открытой по внешней матрице.
12.5.212 — GRE PSK/FastPath (2026-10-13)
Результат, проверки и ограничения: полная запись212. Runtime ux-gre212, SQL/API18, E2E10, native/UI и cleanup подтверждены; auth211 сохранён.
12.5.213 — GRE IPv6 export (2026-10-13)
Статический внутренний ULA и IPv6 fragment проверены на двух CHR и четырёх live UI. Backend ux-gre212, frontend ux-gre213; собственные интерфейсы/адреса/user удалены. Подробности и ограничения: блок213 в журнале. Public IPv6 и произвольный RSC import не приняты.
12.5.214 — GRE badge contrast (2026-10-14)
Подробности: блок214 в журнале. Scoped axe4 и live UI8 прошли; cleanup подтверждён. Backend ux-gre212, frontend ux-gre214.
12.5.215 — OSPF/BFD (2026-10-14)
Пять legacy endpoints возвращают503 при неполном опросе. Успешные envelopes сохранены; SQL25/localHTTP25 и live API/UI приняты. Подробности и границы — журнал. Backend ux-ospf215, frontend ux-gre214; следующий216 — legacy BGP.
12.5.216 — BGP snapshots (2026-10-14)
Неполный BGP poll больше не считается успешным пустым ответом/снимком. GRE при ошибке BGP сохраняется. Production17 и реальный API/UI приняты. Подробности и границы — журнал. Backend ux-bgp216, frontend ux-gre214; следующий217 — WAN runtime.
12.5.217 — WAN runtime (2026-10-14)
Read failures/malformed collections дают502, выключенные устройства409 без native poll, empty success сохранён. Production15 и реальная сверка API/native прошли. Подробности и границы — журнал. Backend ux-wan217, frontend ux-gre214; следующий218 — routing table accessibility.
12.5.218 — заполненные routing tables (2026-10-14)
BGP/OSPF contrast: baseline22/fixed104 cells0 violations; E2E22 и real UI8 passed. Own GRE/OSPF/BGP objects удалены; статическая сверка10×2 прошла. Подробности и границы — журнал. Frontend ux-routing218, backend ux-wan217; следующий219 — GRE snapshot source errors.
12.5.219 — GRE snapshot source (2026-10-14)
Ошибки GRE source отражаются в snapshot; BGP при GRE failure сохраняется. SQL/native10 и actual compiled source2own GRE/UI passed; временные объекты удалены. Подробности и границы — журнал. Backend ux-gre219, frontend ux-routing218; следующий220 — неизвестные GRE flags.
12.5.220 — GRE operational flags (2026-10-14)
Общий reader catalog/config/alerts не подменяет неизвестные flags. Production30/local49 и цельный native lifecycle/Ping/source/UI прошли, own objects удалены. Первичный401 сохранён, причина неизвестна. Подробности и границы — журнал. Backend ux-gre220, frontend ux-routing218; следующий221 — GRE identity guards.