fix(ospf): сопоставлять IPv6 адреса и исключать неоднозначный BFD

This commit is contained in:
Denozordec committed 2026-10-12 09:48:06 +07:00
1 parent 1b63e3ec43
commit e1617f1472
11 files changed
+201 -19

No files matched your search

+18 -2
View File
@@ -1,6 +1,6 @@
# UX/UI: протокол внешней приёмки 12.5
Актуальное продолжение 2026-10-12: завершён 12.5.157 — общая регрессия: 1260 UI + 221 context, все 24 backend профиля, source TypeScript прошли. 348 исходных изображений восстановлены и сверены по SHA256, включая пользовательские изменения. Runtime ux-id156/ux-ospf153 сохранён. Следующий 158 — проверить корректность сопоставления IPv6 OSPF/BFD; внешняя матрица 12.5 остаётся открытой.
Актуальное продолжение 2026-10-12: завершён 12.5.158 — OSPF/BFD сопоставляет эквивалентные IPv6 адреса, отвергает чужую zone/invalid IP и неоднозначные stale duplicate sessions. 5 unit/11 E2E/types/ESLint/frontend build/2 real deployed UI прошли; frontend ux-bfd158, backend ux-id156. Общая регрессия157 принята до этой delta. Следующий159 — native OSPFv3/BFDv6 на собственной GRE паре с cleanup; внешняя матрица12.5 открыта.
IPsec78: реальный PSK responder established, mode-config198.18.78.10 и online=true подтверждены API; точные собственные объекты удалены. Сертификатный/DN online, late failure и history restore остаются открытыми. [Отчёт](ux-ui/acceptance/ipsec-mode-config-2026-10-09.json), [журнал](ux-ui-progress.md).
@@ -696,7 +696,7 @@ flowchart LR
## 12.5.77 — основной блок IPsec (2026-10-09)
Актуальное продолжение 2026-10-12: завершён 12.5.157 — общая регрессия: 1260 UI + 221 context, все 24 backend профиля, source TypeScript прошли. 348 исходных изображений восстановлены и сверены по SHA256, включая пользовательские изменения. Runtime ux-id156/ux-ospf153 сохранён. Следующий 158 — проверить корректность сопоставления IPv6 OSPF/BFD; внешняя матрица 12.5 остаётся открытой.
Актуальное продолжение 2026-10-12: завершён 12.5.158 — OSPF/BFD сопоставляет эквивалентные IPv6 адреса, отвергает чужую zone/invalid IP и неоднозначные stale duplicate sessions. 5 unit/11 E2E/types/ESLint/frontend build/2 real deployed UI прошли; frontend ux-bfd158, backend ux-id156. Общая регрессия157 принята до этой delta. Следующий159 — native OSPFv3/BFDv6 на собственной GRE паре с cleanup; внешняя матрица12.5 открыта.
Подробный объём, протоколы, схема и ограничения: [12.5.77 в журнале](ux-ui-progress.md).
@@ -1727,3 +1727,19 @@ Permanent server-id.test.ts проверяет25 valid/invalid forms без SQL.
Source TypeScript прошёл после остановки тестового Next dev. Все348 tracked изображения восстановлены из сохранённых перед прогоном текущих bytes, каждое сверено по SHA256; сохранены в том числе8 пользовательских GRE/VXLAN изменений. Сгенерированные тестами изображения не заменяют согласованные референсы. Production source не менялся, образы ux-id156/ux-ospf153 повторно не собирались и не развёртывались. RouterOS конфигурация и пароли этим блоком не изменялись.
Протокол: [регрессия157](ux-ui/acceptance/regression-157-2026-10-12.json). Это локальная контролируемая регрессия интерфейса/контекста/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 восстановлен.
Протоколы: [профильные проверки и сборка](ux-ui/acceptance/ospf-bfd-correlation-2026-10-12.json), [реальный развёрнутый интерфейс](ux-ui/acceptance/ospf-bfd-ipv6-smoke-2026-10-12.json). Установленные ReUI/Frame/base-nova переиспользованы без изменения primitives.
| Референс | Схема доработки |
| --- | --- |
| [ReUI Data Grid Filtering2](https://reui.io/preview/base/data-grid-filtering-2?ref=mcp) | Устройство → точный IPv6 peer/интерфейс → достоверное предупреждение → соответствующая BFD сессия |
Следующий159 — native OSPFv3/BFDv6 на собственной GRE паре, short loss/recovery и независимая сверка cleanup. Официальный [BFD manual](https://manual.mikrotik.com/docs/user-guides/routing-and-networking-protocols/unicast/bfd/) описывает IPv4/IPv6 и use-bfd, но текущая страница версии7.26 не заменяет эксперимент на стенде7.24.5. Sustained route gate, scale/IPv6 public WAN/outer и физическая резервность остаются непроверенными;12.5 открыт.
+3 -3
View File
@@ -1,12 +1,12 @@
# План реализации UX/UI по пятичасовым окнам
Актуальное продолжение 2026-10-12: завершён 12.5.157 — общая регрессия: 1260 UI + 221 context, все 24 backend профиля, source TypeScript прошли. 348 исходных изображений восстановлены и сверены по SHA256, включая пользовательские изменения. Runtime ux-id156/ux-ospf153 сохранён. Следующий 158 — проверить корректность сопоставления IPv6 OSPF/BFD; внешняя матрица 12.5 остаётся открытой.
Актуальное продолжение 2026-10-12: завершён 12.5.158 — OSPF/BFD сопоставляет эквивалентные IPv6 адреса, отвергает чужую zone/invalid IP и неоднозначные stale duplicate sessions. 5 unit/11 E2E/types/ESLint/frontend build/2 real deployed UI прошли; frontend ux-bfd158, backend ux-id156. Общая регрессия157 принята до этой delta. Следующий159 — native OSPFv3/BFDv6 на собственной GRE паре с cleanup; внешняя матрица12.5 открыта.
Общий план проекта MikrotikManager. Основан на согласованном плане из задачи; точка продолжения обновлена 2026-10-12. Источник фактического прогресса, проверок и ограничений — [журнал реализации](ux-ui-progress.md). Этот документ задаёт объём и критерии завершения, журнал фиксирует результат.
## Актуальная точка продолжения — 2026-10-12
Актуальное продолжение 2026-10-12: завершён 12.5.157 — общая регрессия: 1260 UI + 221 context, все 24 backend профиля, source TypeScript прошли. 348 исходных изображений восстановлены и сверены по SHA256, включая пользовательские изменения. Runtime ux-id156/ux-ospf153 сохранён. Следующий 158 — проверить корректность сопоставления IPv6 OSPF/BFD; внешняя матрица 12.5 остаётся открытой.
Актуальное продолжение 2026-10-12: завершён 12.5.158 — OSPF/BFD сопоставляет эквивалентные IPv6 адреса, отвергает чужую zone/invalid IP и неоднозначные stale duplicate sessions. 5 unit/11 E2E/types/ESLint/frontend build/2 real deployed UI прошли; frontend ux-bfd158, backend ux-id156. Общая регрессия157 принята до этой delta. Следующий159 — native OSPFv3/BFDv6 на собственной GRE паре с cleanup; внешняя матрица12.5 открыта.
Этапы0–11 завершены в локальных границах журнала. История выполненных внешних блоков и доказательства сохранены в [журнале](ux-ui-stage-12.md) и [протоколе](ux-ui-external-acceptance.md). Реальная Telegram доставка, Portal SSO, multi-instance и оставшиеся профильные сетевые ограничения открыты.
@@ -371,6 +371,6 @@ flowchart LR
## 12.5.77 — основной блок IPsec (2026-10-09)
Актуальное продолжение 2026-10-12: завершён 12.5.157 — общая регрессия: 1260 UI + 221 context, все 24 backend профиля, source TypeScript прошли. 348 исходных изображений восстановлены и сверены по SHA256, включая пользовательские изменения. Runtime ux-id156/ux-ospf153 сохранён. Следующий 158 — проверить корректность сопоставления IPv6 OSPF/BFD; внешняя матрица 12.5 остаётся открытой.
Актуальное продолжение 2026-10-12: завершён 12.5.158 — OSPF/BFD сопоставляет эквивалентные IPv6 адреса, отвергает чужую zone/invalid IP и неоднозначные stale duplicate sessions. 5 unit/11 E2E/types/ESLint/frontend build/2 real deployed UI прошли; frontend ux-bfd158, backend ux-id156. Общая регрессия157 принята до этой delta. Следующий159 — native OSPFv3/BFDv6 на собственной GRE паре с cleanup; внешняя матрица12.5 открыта.
Подробный объём, протоколы, схема и ограничения: [12.5.77 в журнале](ux-ui-progress.md).
+18 -2
View File
@@ -1,6 +1,6 @@
# UX/UI: журнал реализации
Актуальное продолжение 2026-10-12: завершён 12.5.157 — общая регрессия: 1260 UI + 221 context, все 24 backend профиля, source TypeScript прошли. 348 исходных изображений восстановлены и сверены по SHA256, включая пользовательские изменения. Runtime ux-id156/ux-ospf153 сохранён. Следующий 158 — проверить корректность сопоставления IPv6 OSPF/BFD; внешняя матрица 12.5 остаётся открытой.
Актуальное продолжение 2026-10-12: завершён 12.5.158 — OSPF/BFD сопоставляет эквивалентные IPv6 адреса, отвергает чужую zone/invalid IP и неоднозначные stale duplicate sessions. 5 unit/11 E2E/types/ESLint/frontend build/2 real deployed UI прошли; frontend ux-bfd158, backend ux-id156. Общая регрессия157 принята до этой delta. Следующий159 — native OSPFv3/BFDv6 на собственной GRE паре с cleanup; внешняя матрица12.5 открыта.
Общий план: [UX/UI по этапам и пятичасовым окнам](ux-ui-plan.md). План задаёт объём, этот журнал фиксирует выполненные блоки и ограничения. Записи расположены от новых к старым; подробная история этапа12 также сохранена в [ux-ui-stage-12.md](ux-ui-stage-12.md).
@@ -36,7 +36,23 @@
| 10 | Маршрутизация, диагностика, карта и терминал | Завершён в границах локальной приёмки 2026-10-01; блоки 10.1–10.71, внешние ограничения в 10.71 |
| 11А | Пользователи, контейнеры, сертификаты и резервные копии | Завершён в границах локальной приёмки 2026-10-01; 11А.1–11А.33, внешние ограничения в 11А.33 |
| 11Б | Оповещения, сбор данных, интеграции, релизы и настройки | Завершён в границах локальной приёмки 2026-10-03; ограничения и evidence в11Б.7 |
| 12 | Итоговая доступность, адаптивность, производительность и регрессия | Локальная приёмка завершена в границах12.3.83; внешняя12.5 в работе, выполненные блоки1–157 и ограничения ниже. Runtime backend ux-month149/frontend ux-sessions150. |
| 12 | Итоговая доступность, адаптивность, производительность и регрессия | Локальная приёмка завершена в границах12.3.83; внешняя12.5 в работе, выполненные блоки1–158 и ограничения ниже. Runtime backend ux-month149/frontend ux-sessions150. |
## 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 восстановлен.
Протоколы: [профильные проверки и сборка](ux-ui/acceptance/ospf-bfd-correlation-2026-10-12.json), [реальный развёрнутый интерфейс](ux-ui/acceptance/ospf-bfd-ipv6-smoke-2026-10-12.json). Установленные ReUI/Frame/base-nova переиспользованы без изменения primitives.
| Референс | Схема доработки |
| --- | --- |
| [ReUI Data Grid Filtering2](https://reui.io/preview/base/data-grid-filtering-2?ref=mcp) | Устройство → точный IPv6 peer/интерфейс → достоверное предупреждение → соответствующая BFD сессия |
Следующий159 — native OSPFv3/BFDv6 на собственной GRE паре, short loss/recovery и независимая сверка cleanup. Официальный [BFD manual](https://manual.mikrotik.com/docs/user-guides/routing-and-networking-protocols/unicast/bfd/) описывает IPv4/IPv6 и use-bfd, но текущая страница версии7.26 не заменяет эксперимент на стенде7.24.5. Sustained route gate, scale/IPv6 public WAN/outer и физическая резервность остаются непроверенными;12.5 открыт.
## 12.5.157 — общая регрессия после IPv6 и bigint исправлений (2026-10-12)
+19 -3
View File
@@ -1,8 +1,8 @@
# Оставшаяся внешняя приёмка — 2026-10-12
Это актуальная матрица после 12.5.157. Исторические записи сохраняют версии и ограничения на момент выполнения; поздние проверки ниже уточняют их. Этап 12.5 открыт. Успех в двух CHR и одном backend не означает приёмку всех конфигураций, интеграций или полной регрессии.
Это актуальная матрица после 12.5.158. Исторические записи сохраняют версии и ограничения на момент выполнения; поздние проверки ниже уточняют их. Этап 12.5 открыт. Успех в двух CHR и одном backend не означает приёмку всех конфигураций, интеграций или полной регрессии.
Стенд: Debian13/Compose, PostgreSQL18.6, два CHR RouterOS7.24.5. Backend `ux-id156`, frontend `ux-ospf153`; production lab использует AUTH_REQUIRED=false. Подписанные JWT/RBAC проверялись в изолированных процессах. Все собственные объекты112 удалены, исходные13 коллекций×2 (включая logging/certificates/files/routes) проверены; пароли не менялись.
Стенд: Debian13/Compose, PostgreSQL18.6, два CHR RouterOS7.24.5. Backend `ux-id156`, frontend `ux-bfd158`; production lab использует AUTH_REQUIRED=false. Подписанные JWT/RBAC проверялись в изолированных процессах. Все собственные объекты112 удалены, исходные13 коллекций×2 (включая logging/certificates/files/routes) проверены; пароли не менялись.
| Раздел | Подтверждено | Осталось / условие завершения |
| --- | --- | --- |
@@ -18,7 +18,7 @@
| Recursive routes | Production PUT/change/own history restore88, disabled guards, partial/unknown/applied outcomes, live формы/контекст | Автоматический rollback/retry, durable receipts и несколько экземпляров отсутствуют; PUT не является idempotent noop. Полная произвольная legacy catalog миграция не принята |
| Diagnostics/terminal | Allowlist/native reads, Ping/trace/route/MTU/DNS, actual avg-rtt, disabled guards, JWT/live PC/mobile89; real default memory tail/log limits/API/UI133 | DNS использует backend resolver; MTU — ограниченная оценка, не гарантированный максимум. Stop ожидания не доказывает остановку RouterOS команды; arbitrary CLI и physical disconnect не приняты |
| Portal/интеграции | Локальные и isolated JWT guards; UI/API error states в границах журналов | Настоящий Portal issuer/login/отзыв прав; RIPE SDK two-IP/no-fetch passed140, native IPv6 ULA flow pipeline passed145 (IPv4 transport), public IPv6 WAN/local licensed MaxMind/S3/container/certificate jobs и Gitea delivery требуют отдельных тестовых endpoints/аккаунтов. Не отправлять сообщения и не публиковать релиз без соответствующего поручения |
| Общая приёмка | Локальная12.3.83; UI1244/context221/compiled984 parity139; профильные build/E2E/live проверки последующих блоков | Traffic initial live mock-id gate passed141; IPv6 special ranges/cache passed142; unknown RIPE coordinates passed143; IPv6 synthetic UDP/worker/SQL passed144; native CHR ULA/IPFIX/API/UI passed145; ICMPv6/IPv6 endpoint labels passed146; HTTP DTO validation passed147; scoped flow catalog/serverId guards passed148; strict monthly calendar passed149; Sessions labels passed150; application GRE static IPv6 lifecycle151 passed; WireGuard static IPv6 lifecycle152 и disabled SQL/API gates passed; OSPF/BFD boundary/warning153 passed; OSPFv3 routes154 accepted in recorded bounds; BGP IPv6 basic155 passed; bigint ID/SQL guards156 passed; общая UI1260/context221/backend24 regression157 passed; последующие изменения проверять отдельно; scoped axe не означает полную WCAG сертификацию |
| Общая приёмка | Локальная12.3.83; UI1244/context221/compiled984 parity139; профильные build/E2E/live проверки последующих блоков | Traffic initial live mock-id gate passed141; IPv6 special ranges/cache passed142; unknown RIPE coordinates passed143; IPv6 synthetic UDP/worker/SQL passed144; native CHR ULA/IPFIX/API/UI passed145; ICMPv6/IPv6 endpoint labels passed146; HTTP DTO validation passed147; scoped flow catalog/serverId guards passed148; strict monthly calendar passed149; Sessions labels passed150; application GRE static IPv6 lifecycle151 passed; WireGuard static IPv6 lifecycle152 и disabled SQL/API gates passed; OSPF/BFD boundary/warning153 passed; OSPFv3 routes154 accepted in recorded bounds; BGP IPv6 basic155 passed; bigint ID/SQL guards156 passed; общая UI1260/context221/backend24 regression157 passed; IPv6 BFD correlation158 profile/deployed passed; последующие изменения проверять отдельно; scoped axe не означает полную WCAG сертификацию |
Доказательства и точные ограничения: [полная история этапа12](ux-ui-stage-12.md), [внешний протокол](ux-ui-external-acceptance.md), [BGP93](ux-ui/acceptance/bgp-failover-2026-10-10.json), [паспорт стенда](ux-ui-test-server.md). Невыполненные пункты не являются все блокерами данного лабораторного сценария: для выпуска необходимо явно определить требуемые конфигурации и принять их либо согласовать ограничение.
@@ -642,3 +642,19 @@ Permanent server-id.test.ts проверяет25 valid/invalid forms без SQL.
Source TypeScript прошёл после остановки тестового Next dev. Все348 tracked изображения восстановлены из сохранённых перед прогоном текущих bytes, каждое сверено по SHA256; сохранены в том числе8 пользовательских GRE/VXLAN изменений. Сгенерированные тестами изображения не заменяют согласованные референсы. Production source не менялся, образы ux-id156/ux-ospf153 повторно не собирались и не развёртывались. RouterOS конфигурация и пароли этим блоком не изменялись.
Протокол: [регрессия157](ux-ui/acceptance/regression-157-2026-10-12.json). Это локальная контролируемая регрессия интерфейса/контекста/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 восстановлен.
Протоколы: [профильные проверки и сборка](ux-ui/acceptance/ospf-bfd-correlation-2026-10-12.json), [реальный развёрнутый интерфейс](ux-ui/acceptance/ospf-bfd-ipv6-smoke-2026-10-12.json). Установленные ReUI/Frame/base-nova переиспользованы без изменения primitives.
| Референс | Схема доработки |
| --- | --- |
| [ReUI Data Grid Filtering2](https://reui.io/preview/base/data-grid-filtering-2?ref=mcp) | Устройство → точный IPv6 peer/интерфейс → достоверное предупреждение → соответствующая BFD сессия |
Следующий159 — native OSPFv3/BFDv6 на собственной GRE паре, short loss/recovery и независимая сверка cleanup. Официальный [BFD manual](https://manual.mikrotik.com/docs/user-guides/routing-and-networking-protocols/unicast/bfd/) описывает IPv4/IPv6 и use-bfd, но текущая страница версии7.26 не заменяет эксперимент на стенде7.24.5. Sustained route gate, scale/IPv6 public WAN/outer и физическая резервность остаются непроверенными;12.5 открыт.
+17 -1
View File
@@ -1,6 +1,6 @@
# Этап 12: итоговая приёмка UX/UI
Актуальное продолжение 2026-10-12: завершён 12.5.157 — общая регрессия: 1260 UI + 221 context, все 24 backend профиля, source TypeScript прошли. 348 исходных изображений восстановлены и сверены по SHA256, включая пользовательские изменения. Runtime ux-id156/ux-ospf153 сохранён. Следующий 158 — проверить корректность сопоставления IPv6 OSPF/BFD; внешняя матрица 12.5 остаётся открытой.
Актуальное продолжение 2026-10-12: завершён 12.5.158 — OSPF/BFD сопоставляет эквивалентные IPv6 адреса, отвергает чужую zone/invalid IP и неоднозначные stale duplicate sessions. 5 unit/11 E2E/types/ESLint/frontend build/2 real deployed UI прошли; frontend ux-bfd158, backend ux-id156. Общая регрессия157 принята до этой delta. Следующий159 — native OSPFv3/BFDv6 на собственной GRE паре с cleanup; внешняя матрица12.5 открыта.
План: [ux-ui-plan.md](ux-ui-plan.md). Фактические результаты: [ux-ui-progress.md](ux-ui-progress.md). Подготовлен после сводных проверок 11Б; завершение каждого блока требует локального коммита без push.
@@ -3032,3 +3032,19 @@ Permanent server-id.test.ts проверяет25 valid/invalid forms без SQL.
Source TypeScript прошёл после остановки тестового Next dev. Все348 tracked изображения восстановлены из сохранённых перед прогоном текущих bytes, каждое сверено по SHA256; сохранены в том числе8 пользовательских GRE/VXLAN изменений. Сгенерированные тестами изображения не заменяют согласованные референсы. Production source не менялся, образы ux-id156/ux-ospf153 повторно не собирались и не развёртывались. RouterOS конфигурация и пароли этим блоком не изменялись.
Протокол: [регрессия157](ux-ui/acceptance/regression-157-2026-10-12.json). Это локальная контролируемая регрессия интерфейса/контекста/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 восстановлен.
Протоколы: [профильные проверки и сборка](ux-ui/acceptance/ospf-bfd-correlation-2026-10-12.json), [реальный развёрнутый интерфейс](ux-ui/acceptance/ospf-bfd-ipv6-smoke-2026-10-12.json). Установленные ReUI/Frame/base-nova переиспользованы без изменения primitives.
| Референс | Схема доработки |
| --- | --- |
| [ReUI Data Grid Filtering2](https://reui.io/preview/base/data-grid-filtering-2?ref=mcp) | Устройство → точный IPv6 peer/интерфейс → достоверное предупреждение → соответствующая BFD сессия |
Следующий159 — native OSPFv3/BFDv6 на собственной GRE паре, short loss/recovery и независимая сверка cleanup. Официальный [BFD manual](https://manual.mikrotik.com/docs/user-guides/routing-and-networking-protocols/unicast/bfd/) описывает IPv4/IPv6 и use-bfd, но текущая страница версии7.26 не заменяет эксперимент на стенде7.24.5. Sustained route gate, scale/IPv6 public WAN/outer и физическая резервность остаются непроверенными;12.5 открыт.
+18 -2
View File
@@ -1,6 +1,6 @@
# Тестовый сервер UX/UI — 2026-10-10
Сервер161.104.46.222: завершён 12.5.157 — общая регрессия: 1260 UI + 221 context, все 24 backend профиля, source TypeScript прошли. 348 исходных изображений восстановлены и сверены по SHA256, включая пользовательские изменения. Runtime ux-id156/ux-ospf153 сохранён. Следующий 158 — проверить корректность сопоставления IPv6 OSPF/BFD; внешняя матрица 12.5 остаётся открытой.
Сервер161.104.46.222: завершён 12.5.158 — OSPF/BFD сопоставляет эквивалентные IPv6 адреса, отвергает чужую zone/invalid IP и неоднозначные stale duplicate sessions. 5 unit/11 E2E/types/ESLint/frontend build/2 real deployed UI прошли; frontend ux-bfd158, backend ux-id156. Общая регрессия157 принята до этой delta. Следующий159 — native OSPFv3/BFDv6 на собственной GRE паре с cleanup; внешняя матрица12.5 открыта.
| Параметр | Проверенное состояние |
| --- | --- |
@@ -14,7 +14,7 @@
| PostgreSQL | postgres:18-alpine,18.6;mmapp-test-postgres healthy;SELECT version() passed |
| Данные | Отдельный Compose project mmapp-test,том mmapp-test_mmapp-pgdata и каталог ./data |
| Доступ | PostgreSQL не публикуется;frontend3000/backend8000 привязаны к127.0.0.1 после запуска |
| Образы приложения | mmapp-test/backend:ux-id156 и mmapp-test/frontend:ux-ospf153; запущены |
| Образы приложения | mmapp-test/backend:ux-id156 и mmapp-test/frontend:ux-bfd158; запущены |
Compose SHA256:3052bd6ab5d9865f97605cebfb5ff27a4410cd3357b81153a65a87fb7c92582f. OptionalBACKEND_IMAGE_TAG позволяетобновлятьbackendотдельно. Локальный и удалённый файлы совпали. Шаблоны: [Compose](../deploy/docker-compose.test.yml), [env без секретов](../deploy/env.test.example).
@@ -1458,3 +1458,19 @@ Permanent server-id.test.ts проверяет25 valid/invalid forms без SQL.
Source TypeScript прошёл после остановки тестового Next dev. Все348 tracked изображения восстановлены из сохранённых перед прогоном текущих bytes, каждое сверено по SHA256; сохранены в том числе8 пользовательских GRE/VXLAN изменений. Сгенерированные тестами изображения не заменяют согласованные референсы. Production source не менялся, образы ux-id156/ux-ospf153 повторно не собирались и не развёртывались. RouterOS конфигурация и пароли этим блоком не изменялись.
Протокол: [регрессия157](ux-ui/acceptance/regression-157-2026-10-12.json). Это локальная контролируемая регрессия интерфейса/контекста/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 восстановлен.
Протоколы: [профильные проверки и сборка](ux-ui/acceptance/ospf-bfd-correlation-2026-10-12.json), [реальный развёрнутый интерфейс](ux-ui/acceptance/ospf-bfd-ipv6-smoke-2026-10-12.json). Установленные ReUI/Frame/base-nova переиспользованы без изменения primitives.
| Референс | Схема доработки |
| --- | --- |
| [ReUI Data Grid Filtering2](https://reui.io/preview/base/data-grid-filtering-2?ref=mcp) | Устройство → точный IPv6 peer/интерфейс → достоверное предупреждение → соответствующая BFD сессия |
Следующий159 — native OSPFv3/BFDv6 на собственной GRE паре, short loss/recovery и независимая сверка cleanup. Официальный [BFD manual](https://manual.mikrotik.com/docs/user-guides/routing-and-networking-protocols/unicast/bfd/) описывает IPv4/IPv6 и use-bfd, но текущая страница версии7.26 не заменяет эксперимент на стенде7.24.5. Sustained route gate, scale/IPv6 public WAN/outer и физическая резервность остаются непроверенными;12.5 открыт.
@@ -0,0 +1,24 @@
{
"date": "2026-10-12",
"block": "12.5.158",
"unit": {
"passed": 5
},
"e2e": {
"passed": 11
},
"typescriptExitCode": 0,
"eslintExitCode": 0,
"frontendBuildExitCode": 0,
"sourceSha256": "66752dd8bf9378ffca13da825d14e3ebd5b4b7daffe29df5e5c367e08cf46fc8",
"remoteSourceHashMatched": true,
"runtime": {
"frontend": "ux-bfd158",
"backend": "ux-id156"
},
"startup": {
"firstImmediateCurlStatus": "000",
"subsequentBrowserCasesHttp200": 2
},
"scope": "Canonical IPv6/zone/invalid address/duplicate guards; no native BFDv6 mutation or SLA acceptance; full regression157 predates this delta"
}
@@ -0,0 +1,48 @@
{
"date": "2026-10-12",
"block": "12.5.158",
"runtime": {
"backend": "ux-id156",
"frontend": "ux-bfd158"
},
"cases": [
{
"width": 1440,
"status": 200,
"api": [
{
"path": "/api/servers",
"status": 200
},
{
"path": "/api/ospf/catalog",
"status": 200
}
],
"pageErrors": [],
"noOverflow": true,
"noFalseConflict": true
},
{
"width": 320,
"status": 200,
"api": [
{
"path": "/api/ospf/catalog",
"status": 200
},
{
"path": "/api/servers",
"status": 200
}
],
"pageErrors": [],
"noOverflow": true,
"noFalseConflict": true
}
],
"bounds": [
"Read-only deployed UI with real backend after native fixture cleanup; no positive native BFDv6 claim",
"Positive IPv6 conflict and recovery covered by controlled E2E separately"
]
}
+17
View File
@@ -29,3 +29,20 @@ test("topology does not infer Down from missing or transitional evidence", () =>
assert.equal(ospfNodeState(["2-Way", "Down"]), "2-Way")
assert.equal(ospfNodeState(["Full", "Unknown"]), "Full")
})
test("BFD correlation compares IPv6 addresses canonically within their interface scope", () => {
const neighbor = { localRouter: "1", localIface: "gre-own", neighborAddress: "FE80:0000:0000:0000:0000:0000:0000:0002%gre-own", state: "Full" as const }
const iface = { serverId: "1", interfaceName: "gre-own", active: true, useBfd: true }
const session = { serverId: "1", iface: "gre-own", remoteAddr: "fe80::2", state: "Down" as const, multihop: false }
assert.deepEqual(ospfBfdConflicts([neighbor], [iface], [session]), [neighbor])
for (const remoteAddr of ["fe80::3", "fe80::2%other", "fe80::2%", "fe80::2%gre-own%extra"]) assert.deepEqual(ospfBfdConflicts([neighbor], [iface], [{ ...session, remoteAddr }]), [])
for (const neighborAddress of ["fe80::2%other", "fe80::2%", "fe80::2%gre-own%extra"]) assert.deepEqual(ospfBfdConflicts([{ ...neighbor, neighborAddress }], [iface], [session]), [])
})
test("invalid peer strings and stale duplicate sessions cannot prove an OSPF/BFD conflict", () => {
const neighbor = { localRouter: "1", localIface: "gre-own", neighborAddress: "198.18.153.2", state: "Full" as const }
const iface = { serverId: "1", interfaceName: "gre-own", active: true, useBfd: true }
const session = { serverId: "1", iface: "gre-own", remoteAddr: neighbor.neighborAddress, state: "Down" as const, multihop: false }
assert.deepEqual(ospfBfdConflicts([neighbor], [iface], [session, { ...session, dataUnknown: true }]), [])
for (const address of ["peer.example", "999.18.153.2", "0198.18.153.2", "fe80::invalid", ":::", "fe80::2/64", ""]) assert.deepEqual(ospfBfdConflicts([{ ...neighbor, neighborAddress: address }], [iface], [{ ...session, remoteAddr: address }]), [])
})
+14 -3
View File
@@ -19,11 +19,22 @@ export function ospfBfdConflicts<T extends { localRouter: string; localIface: st
interfaces: Array<{ serverId: string; interfaceName: string; useBfd?: boolean | null; active?: boolean | null; dataUnknown?: boolean }>,
sessions: Array<{ serverId: string; iface: string; remoteAddr: string; state: BfdState; multihop?: boolean | null; dataUnknown?: boolean }>,
): T[] {
const ip = (value: string) => value.split("%")[0]?.toLowerCase() ?? ""
const ip = (value: string, iface: string): string | null => {
const [address, zone, ...extra] = value.trim().split("%")
if (!address || extra.length || (zone !== undefined && zone !== iface)) return null
if (address.includes(":")) {
if (!/^[0-9a-f:.]+$/i.test(address)) return null
try { return new URL(`http://[${address}]/`).hostname } catch { return null }
}
const parts = address.split(".")
return parts.length === 4 && parts.every(p => /^(0|[1-9]\d{0,2})$/.test(p) && Number(p) <= 255) ? address : null
}
return neighbors.filter(n => {
if (n.dataUnknown || n.state !== "Full" || !n.neighborAddress || !n.localIface) return false
if (!interfaces.some(i => !i.dataUnknown && i.active === true && i.useBfd === true && i.serverId === n.localRouter && i.interfaceName === n.localIface)) return false
const matching = sessions.filter(s => !s.dataUnknown && s.multihop === false && s.serverId === n.localRouter && s.iface === n.localIface && ip(s.remoteAddr) === ip(n.neighborAddress!))
return matching.length === 1 && (matching[0]!.state === "Down" || matching[0]!.state === "AdminDown")
const peer = ip(n.neighborAddress, n.localIface)
if (!peer) return false
const matching = sessions.filter(s => s.multihop === false && s.serverId === n.localRouter && s.iface === n.localIface && ip(s.remoteAddr, s.iface) === peer)
return matching.length === 1 && !matching[0]!.dataUnknown && (matching[0]!.state === "Down" || matching[0]!.state === "AdminDown")
})
}
+5 -3
View File
@@ -1,12 +1,13 @@
import { test, expect } from "@playwright/test"
for (const width of [1440, 320]) {
test(`OSPF Full/BFD Down: предупреждение, scope и recovery, ширина ${width}`, async ({ page }) => {
for (const ipv6 of [false, true]) {
test(`OSPF Full/BFD Down: предупреждение, scope и recovery, IPv${ipv6 ? 6 : 4}, ширина ${width}`, async ({ page }) => {
await page.setViewportSize({ width, height: 1000 })
let phase = "down"
const base = { serverId: 1, serverName: "CHR 1", serverSite: "", serverCountry: "RU" }
const neighbor = { ...base, id: "*n", address: "198.18.153.2", routerId: "198.18.253.2", instance: "own", area: "own", areaId: "0.0.0.0", interface: "gre-own", state: "Full", uptime: "1m", stateChanges: 1, priority: 1 }
const neighbor = { ...base, id: "*n", address: ipv6 ? "FE80:0000:0000:0000:0000:0000:0000:0002%gre-own" : "198.18.153.2", routerId: "198.18.253.2", instance: "own", area: "own", areaId: "0.0.0.0", interface: "gre-own", state: "Full", uptime: "1m", stateChanges: 1, priority: 1 }
const iface = { ...base, id: "*i", instance: "own", area: "own", areaId: "0.0.0.0", interface: "gre-own", cost: 10, type: "ptp", disabled: false, inactive: false, priority: 1, helloInterval: 1, deadInterval: 20, useBfd: true }
const bfd = { ...base, id: "*b", localAddr: "198.18.153.1", remoteAddr: "198.18.153.2", interface: "gre-own", state: "Down", uptime: "1s", multihop: false, multiplier: 3, txInterval: 200, rxInterval: 200, holdTime: null, packetsRx: 10, packetsTx: 20, stateChanges: 1 }
const bfd = { ...base, id: "*b", localAddr: ipv6 ? "fe80::1" : "198.18.153.1", remoteAddr: ipv6 ? "fe80::2" : "198.18.153.2", interface: "gre-own", state: "Down", uptime: "1s", multihop: false, multiplier: 3, txInterval: 200, rxInterval: 200, holdTime: null, packetsRx: 10, packetsTx: 20, stateChanges: 1 }
const errors: string[] = []
page.on("pageerror", e => errors.push(e.message))
await page.route("**/health", route => route.fulfill({ json: { ok: true } }))
@@ -34,4 +35,5 @@ for (const width of [1440, 320]) {
}
expect(errors).toEqual([])
})
}
}