From 51a579d370d8b8d8aac22e91024f521f7749c3a8 Mon Sep 17 00:00:00 2001 From: Denozordec Date: Wed, 14 Oct 2026 01:39:35 +0700 Subject: [PATCH] =?UTF-8?q?fix(gre):=20=D0=BD=D0=B5=20=D0=BF=D0=BE=D0=B4?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D1=8F=D1=82=D1=8C=20=D0=BD=D0=B5=D0=B8=D0=B7?= =?UTF-8?q?=D0=B2=D0=B5=D1=81=D1=82=D0=BD=D1=8B=D0=B5=20=D1=84=D0=BB=D0=B0?= =?UTF-8?q?=D0=B3=D0=B8=20=D1=81=D0=BE=D1=81=D1=82=D0=BE=D1=8F=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=D0=BC=20=D1=82=D1=83=D0=BD=D0=BD=D0=B5=D0=BB=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../acceptance/gre-observed-flags-sql.mjs | 27 ++ backend/src/services/gre-ipv6.test.ts | 2 +- backend/src/services/gre-live.ts | 6 +- backend/src/services/gre-observed-state.ts | 12 + backend/src/services/gre-tunnels-live.test.ts | 10 + backend/src/services/gre-tunnels-live.ts | 9 +- docs/ux-ui-external-acceptance.md | 6 +- docs/ux-ui-plan.md | 2 +- docs/ux-ui-progress.md | 14 +- docs/ux-ui-remaining-acceptance.md | 10 +- docs/ux-ui-stage-12.md | 15 +- docs/ux-ui-test-server.md | 6 +- docs/ux-ui/acceptance/gre220-baseline.json | 292 ++++++++++++++++++ .../gre220-build-proof-2026-10-14.json | 23 ++ .../gre220-deployment-2026-10-14.json | 21 ++ docs/ux-ui/acceptance/gre220-fixed.json | 292 ++++++++++++++++++ ...220-initial-native-failure-2026-10-14.json | 47 +++ .../gre220-native-live-2026-10-14.json | 100 ++++++ 18 files changed, 877 insertions(+), 17 deletions(-) create mode 100644 backend/scripts/acceptance/gre-observed-flags-sql.mjs create mode 100644 backend/src/services/gre-observed-state.ts create mode 100644 docs/ux-ui/acceptance/gre220-baseline.json create mode 100644 docs/ux-ui/acceptance/gre220-build-proof-2026-10-14.json create mode 100644 docs/ux-ui/acceptance/gre220-deployment-2026-10-14.json create mode 100644 docs/ux-ui/acceptance/gre220-fixed.json create mode 100644 docs/ux-ui/acceptance/gre220-initial-native-failure-2026-10-14.json create mode 100644 docs/ux-ui/acceptance/gre220-native-live-2026-10-14.json diff --git a/backend/scripts/acceptance/gre-observed-flags-sql.mjs b/backend/scripts/acceptance/gre-observed-flags-sql.mjs new file mode 100644 index 00000000..d56e2dd3 --- /dev/null +++ b/backend/scripts/acceptance/gre-observed-flags-sql.mjs @@ -0,0 +1,27 @@ +import assert from 'node:assert/strict' +import fs from 'node:fs' +import {createServer} from 'node:http' +import {randomBytes} from 'node:crypto' +const database=process.env.MMAPP_OWN_SQL_DB,url=new URL(process.env.DATABASE_URL) +assert(/^mm_accept_166_\d+$/.test(database??''));assert.equal(url.pathname,'/'+database);assert.equal(url.username,database) +process.env.AUTH_REQUIRED='true';process.env.AUTH_JWT_SECRET=randomBytes(32).toString('hex');process.env.AUTH_ISSUER='https://own220.invalid';process.env.AUTH_PORTAL_URL='https://own220.invalid' +const {pool,closePool}=await import('/app/backend/dist/db/index.js'),{initDatabase}=await import('/app/backend/dist/db/bootstrap.js'),{collectGreBgpSnapshotOnce}=await import('/app/backend/dist/services/gre-bgp-snapshot-collector.js'),{buildApp}=await import('/app/backend/dist/index.js') +assert.equal((await pool.query('SELECT current_database() AS name')).rows[0].name,database);assert(Object.values((await pool.query('SELECT rolsuper,rolcreatedb,rolcreaterole,rolbypassrls FROM pg_roles WHERE rolname=current_user')).rows[0]).every(v=>v===false)) +const baseline=process.env.MMAPP_BASELINE==='true',cases=[];let app,nativeCalls=0,nativeWrites=0,disabledCalls=0,flags={running:'true',disabled:'false'} +const fixture=label=>createServer((req,res)=>{nativeCalls++;if(label==='disabled')disabledCalls++;if(req.method!=='GET')nativeWrites++;res.setHeader('content-type','application/json');const gre=req.url==='/rest/interface/gre',bgp=req.url==='/rest/routing/bgp/session',row=gre?{'.id':'*1',name:'own220-gre',...(label==='second'?flags:{running:'true',disabled:'false'})}:{'.id':'*1',name:'own220-peer',established:'true','remote.as':'65220','local.as':'65221'};res.end(JSON.stringify(gre||bgp?[row]:[]))}) +const natives=['first','second','disabled'].map(fixture);for(const n of natives)await new Promise(r=>n.listen(0,'127.0.0.1',r)) +const report={date:'2026-10-14',block:'12.5.220',baseline,database,cases,scope:'Actual compiled GRE operational flags and actual snapshot collector, owned SQL/native HTTP fixture; signed reader/authenticated GRE API',passed:false} +try{ + await initDatabase();for(let i=0;irow.targetLabel.endsWith('own220-1'));assert(row);const expected=baseline?flags.disabled==='true'?'down':flags.running==='true'?'up':'degraded':off?'down':['true','yes'].includes(flags.running??'')?'up':'degraded';assert.equal(row.status,expected)} + const api=await app.inject({method:'GET',url:'/api/gre/tunnels',headers}),body=api.json();assert.equal(api.statusCode,200);assert.equal(body.failures.length,unknown&&!baseline?1:0);assert.equal(body.tunnels.length,unknown&&!baseline?1:2);cases.push({phase:item.name,endpoint:'GRE authenticated catalog',status:200,tunnels:body.tunnels.length,failures:body.failures.length}); + cases.push({phase:item.name,flags,greWritten:snapshot.greWritten,bgpWritten:2,sourceErrors:snapshot.errors.length,secondStatus:snapshot.greTunnels.find(row=>row.targetLabel.endsWith('own220-1'))?.status??null,nativeCalls:nativeCalls-before}) + } + + assert.equal(nativeWrites,0);assert.equal(disabledCalls,0);report.passed=true +}catch(e){report.errorName=e.name;fs.writeFileSync('/app/backend/acceptance/gre220-private.log',String(e.stack??e),{mode:0o600})}finally{if(app)await app.close();for(const n of natives){n.closeAllConnections();await new Promise(r=>n.close(r))}await closePool();report.nativeWrites=nativeWrites;report.disabledHomeRouterCalls=disabledCalls;fs.writeFileSync('/app/backend/acceptance/gre220-'+(baseline?'baseline':'fixed')+'.json',JSON.stringify(report,null,2));console.log(JSON.stringify(report))}if(!report.passed)process.exitCode=1 diff --git a/backend/src/services/gre-ipv6.test.ts b/backend/src/services/gre-ipv6.test.ts index 16a3eba4..59aeed21 100644 --- a/backend/src/services/gre-ipv6.test.ts +++ b/backend/src/services/gre-ipv6.test.ts @@ -5,7 +5,7 @@ import { MikrotikClient } from "./mikrotik.js" import type { servers } from "../db/schema.js" const server = { id: 1, name: "CHR", enabled: true } as typeof servers.$inferSelect -const raw = [{ ".id": "*g", name: "own-gre", "remote-address": "192.0.2.1", running: "true" }] +const raw = [{ ".id": "*g", name: "own-gre", "remote-address": "192.0.2.1", running: "true", disabled: "false" }] const rows = [ { ".id": "*1", interface: "own-gre", address: "10.1.0.1/30" }, { ".id": "*1", interface: "own-gre", address: "fd00:151::1/64", advertise: "yes" }, diff --git a/backend/src/services/gre-live.ts b/backend/src/services/gre-live.ts index 6b164224..812e2292 100644 --- a/backend/src/services/gre-live.ts +++ b/backend/src/services/gre-live.ts @@ -12,6 +12,7 @@ import { type GreSnapshot, } from "./entity-snapshots.js" import { captureAndAppendRevision } from "./config-revisions.js" +import { readGreObservedState } from "./gre-observed-state.js" type ServerRow = typeof servers.$inferSelect @@ -142,8 +143,7 @@ export function mapGreLive( ifaceAddrs.sort((a, b) => Number(Boolean(a.disabled)) - Number(Boolean(b.disabled)) || a.address.localeCompare(b.address)) const localInnerIp = ifaceAddrs[0]?.address || fromComment.localInnerIp const secret = (g["ipsec-secret"] ?? "").trim() - const disabled = rosDisabled(g.disabled) - const running = g.running === "true" || g.running === "yes" + const { disabled, status } = readGreObservedState(g, name) gre.push({ name, @@ -183,7 +183,7 @@ export function mapGreLive( allowFastPath: g["allow-fast-path"] !== "false" && g["allow-fast-path"] !== "no", comment: readGreComment(g.comment).comment, enabled: !disabled, - status: disabled ? "down" : running ? "up" : "degraded", + status, }) }) diff --git a/backend/src/services/gre-observed-state.ts b/backend/src/services/gre-observed-state.ts new file mode 100644 index 00000000..acc035cc --- /dev/null +++ b/backend/src/services/gre-observed-state.ts @@ -0,0 +1,12 @@ +import { observedBoolean } from "./ospf-observed-values.js" + +/** Disabled is authoritative; an enabled interface also needs a known running flag. */ +export function readGreObservedState(flags: { running?: string; disabled?: string }, name: string) { + const disabled = observedBoolean(flags.disabled) + const running = observedBoolean(flags.running) + if (disabled === null || (disabled === false && running === null)) { + throw new Error(`Не подтверждено состояние GRE ${name}`) + } + const status: "up" | "down" | "degraded" = disabled ? "down" : running ? "up" : "degraded" + return { disabled, status } +} diff --git a/backend/src/services/gre-tunnels-live.test.ts b/backend/src/services/gre-tunnels-live.test.ts index 9845929d..b17dd4a0 100644 --- a/backend/src/services/gre-tunnels-live.test.ts +++ b/backend/src/services/gre-tunnels-live.test.ts @@ -12,3 +12,13 @@ for(const phase of ['populated','empty','partial','failed','disabled','sync-fail if(phase==='disabled')assert.equal(calls,0) } console.log('GRE alert source: populated/empty/partial/all-failed/disabled/sync error; BGP control preserved, per-device errors retained') +import {mapGreLive} from './gre-live.js' +import {mapGreAlertRow} from './gre-tunnels-live.js' +let combinations=0 +for(const disabled of ['true','yes','false','no',undefined,'','junk'])for(const running of ['true','yes','false','no',undefined,'','junk']){ + const row={'.id':'*1',name:'own-flags',disabled,running},off=['true','yes'].includes(disabled??''),on=['false','no'].includes(disabled??''),runningKnown=['true','yes','false','no'].includes(running??'') + if(off||on&&runningKnown){const expected=off?'down':['true','yes'].includes(running??'')?'up':'degraded';assert.equal(mapGreAlertRow(devices[0],row).status,expected);assert.equal(mapGreLive(devices[0],[row],[]).tunnels[0].status,expected)} + else {assert.throws(()=>mapGreAlertRow(devices[0],row),/Не подтверждено состояние GRE/);assert.throws(()=>mapGreLive(devices[0],[row],[]),/Не подтверждено состояние GRE/)} + combinations++ +} +console.log('GRE flags: '+combinations+' combinations; true/false/yes/no, absent/blank/invalid, disabled state independent of running') diff --git a/backend/src/services/gre-tunnels-live.ts b/backend/src/services/gre-tunnels-live.ts index 98acd913..22199ea2 100644 --- a/backend/src/services/gre-tunnels-live.ts +++ b/backend/src/services/gre-tunnels-live.ts @@ -3,6 +3,7 @@ import { db } from "../db/index.js" import { servers } from "../db/schema.js" import { MikrotikClient } from "./mikrotik.js" import { readInternetPathRows } from "./internet-path-snapshot.js" +import { readGreObservedState } from "./gre-observed-state.js" type ServerRow = typeof servers.$inferSelect @@ -29,10 +30,8 @@ export type GreTunnelLiveRow = { status: GreTunnelLiveStatus } -function mapGreRow(server: ServerRow, g: RosGre, idx: number): GreTunnelLiveRow { - const running = g.running === "true" - const disabled = g.disabled === "true" - const status: GreTunnelLiveStatus = disabled ? "down" : running ? "up" : "degraded" +export function mapGreAlertRow(server: ServerRow, g: RosGre, idx = 0): GreTunnelLiveRow { + const { status } = readGreObservedState(g, g.name ?? g[".id"] ?? "") const sn = String(server.name ?? "").trim() || String(server.host ?? "").trim() || String(server.id) const tn = (String(g.name ?? "").trim() || String(g[".id"] ?? "").trim() || `gre-${idx + 1}`).trim() const label = `${tn} / ${sn}`.trim() @@ -43,7 +42,7 @@ async function fetchGreForServer(server: ServerRow): Promise const client = MikrotikClient.fromServer(server) const greRaw = readInternetPathRows(await client.get("/interface/gre"), "GRE alert source", [".id", "name"]) if (new Set(greRaw.map(row => row[".id"])).size !== greRaw.length) throw new Error("Повторяющиеся ID GRE") - return greRaw.map((g, idx) => mapGreRow(server, g, idx)) + return greRaw.map((g, idx) => mapGreAlertRow(server, g, idx)) } interface GreAlertDependencies { diff --git a/docs/ux-ui-external-acceptance.md b/docs/ux-ui-external-acceptance.md index f66c368b..50974c93 100644 --- a/docs/ux-ui-external-acceptance.md +++ b/docs/ux-ui-external-acceptance.md @@ -1,6 +1,6 @@ # UX/UI: протокол внешней приёмки 12.5 -Актуальное продолжение 2026-10-14: блок219 завершён. GRE source snapshots больше не подавляет per-device ошибки; повреждённые records/duplicate native IDs отклоняются. BGP observations сохраняются при GRE failure. Четыре профиля, SQL/native10, compiled actual source2own GRE и UI1440/320 прошли; own DB/roles/tunnels удалены. Backend ux-gre219/compiled1052/source486 matched, frontend ux-routing218. Следующий220 — неизвестные/некорректные GRE operational flags в snapshots. Этап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 остаются открытыми. [Отчёт](ux-ui/acceptance/ipsec-mode-config-2026-10-09.json), [журнал](ux-ui-progress.md). @@ -2603,3 +2603,7 @@ BGP/OSPF contrast: baseline22/fixed104 cells0 violations; E2E22 и real UI8 pass ## 12.5.219 — GRE snapshot source (2026-10-14) Ошибки GRE source отражаются в snapshot; BGP при GRE failure сохраняется. SQL/native10 и actual compiled source2own GRE/UI passed; временные объекты удалены. Подробности и границы — [журнал](ux-ui-progress.md). 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 сохранён, причина неизвестна. Подробности и границы — [журнал](ux-ui-progress.md). Backend ux-gre220, frontend ux-routing218; следующий221 — GRE identity guards. diff --git a/docs/ux-ui-plan.md b/docs/ux-ui-plan.md index c6562d12..8a5d14b0 100644 --- a/docs/ux-ui-plan.md +++ b/docs/ux-ui-plan.md @@ -1,6 +1,6 @@ # План реализации UX/UI по пятичасовым окнам -Актуальное продолжение 2026-10-14: блок219 завершён. GRE source snapshots больше не подавляет per-device ошибки; повреждённые records/duplicate native IDs отклоняются. BGP observations сохраняются при GRE failure. Четыре профиля, SQL/native10, compiled actual source2own GRE и UI1440/320 прошли; own DB/roles/tunnels удалены. Backend ux-gre219/compiled1052/source486 matched, frontend ux-routing218. Следующий220 — неизвестные/некорректные GRE operational flags в snapshots. Этап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 открыт. Общий план проекта MikrotikManager. Основан на согласованном плане из задачи; точка продолжения обновлена 2026-10-13. Источник фактического прогресса, проверок и ограничений — [журнал реализации](ux-ui-progress.md). Этот документ задаёт объём и критерии завершения, журнал фиксирует результат. diff --git a/docs/ux-ui-progress.md b/docs/ux-ui-progress.md index 49dd7268..3e503465 100644 --- a/docs/ux-ui-progress.md +++ b/docs/ux-ui-progress.md @@ -1,6 +1,6 @@ # UX/UI: журнал реализации -Актуальное продолжение 2026-10-14: блок219 завершён. GRE source snapshots больше не подавляет per-device ошибки; повреждённые records/duplicate native IDs отклоняются. BGP observations сохраняются при GRE failure. Четыре профиля, SQL/native10, compiled actual source2own GRE и UI1440/320 прошли; own DB/roles/tunnels удалены. Backend ux-gre219/compiled1052/source486 matched, frontend ux-routing218. Следующий220 — неизвестные/некорректные GRE operational flags в snapshots. Этап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 открыт. Общий план: [UX/UI по этапам и пятичасовым окнам](ux-ui-plan.md). План задаёт объём, этот журнал фиксирует выполненные блоки и ограничения. Записи расположены от новых к старым; подробная история этапа12 также сохранена в [ux-ui-stage-12.md](ux-ui-stage-12.md). @@ -38,6 +38,18 @@ | 11Б | Оповещения, сбор данных, интеграции, релизы и настройки | Завершён в границах локальной приёмки 2026-10-03; ограничения и evidence в11Б.7 | | 12 | Итоговая доступность, адаптивность, производительность и регрессия | Локальная приёмка завершена в границах12.3.83; внешняя12.5 в работе, выполненные блоки1–196 и ограничения ниже. Runtime backend/frontend ux-peak196. | +## 12.5.220 — подтверждённые operational flags GRE (2026-10-14) + +Общий readGreObservedState используется в live catalog/config snapshot и alert source. true/false/yes/no читаются одинаково; disabled=true подтверждает down независимо от running. При неизвестном disabled или running у enabled interface опрос устройства отклоняется. Достоверные up/down/degraded сохранены; главная API-envelope по-прежнему передаёт failures по устройствам, а source snapshot сообщает GRE error и сохраняет BGP. Unknown metadata больше не выдаётся за подтверждённый operational status. Другие параметры/defaults GRE этим блоком не объявляются полностью проверенными. + +Local49 комбинаций проверили оба reader пути. Профили live-maps14 и config-sync6, build прошли; optional SQL branch network-disabled-server без его специального env skipped, не считается новой SQL приёмкой. Первая IPv6 fixture имела running=true, но не имела disabled: дополнена explicit false, повтор passed. Baseline ux-gre219/fixed ux-gre220 по30 production checks:15 flags через compiled snapshot collector и signed reader GRE API. Unknown flags дают sourceError и per-device API failure; здоровое устройство остаётся в catalog. BGP2 control rows сохраняются. Own DB/roles удалены, native writes0. + +Backend ux-gre220 compiled1056/source488 matched, healthy; frontend ux-routing218 сохранён. Первая live попытка прервана native401104.165.244.7; точный failed request path не записан. Cleanup созданных own GRE сообщил успех. Шесть последующих native checks200 на обоих CHR с теми же credentials; root cause не установлен. Новый цельный run использовал Connection close в прямых контрольных REST calls; это не causal proof причины401 и не production auth retry. + +В повторном run own GRE2/IPv4inner поднялись up, Ping3/3 в обе стороны. Actual compiled collector read lab DB/native и подтвердил own up2/sourceErrors0 без scheduler history write. UI1440/320 показал own rows без page errors/mutations. Disable одного: native/API down + peer degraded; enable: recovery up/up и повторный Ping3/3 обоих. Own interfaces/addresses удалены, absence API/native проверен; пароли не менялись. Это controlled краткая loss/recovery, не physical WAN/SLA/длительная устойчивость. + +Протоколы: [baseline](ux-ui/acceptance/gre220-baseline.json), [fixed](ux-ui/acceptance/gre220-fixed.json), [build](ux-ui/acceptance/gre220-build-proof-2026-10-14.json), [deployment](ux-ui/acceptance/gre220-deployment-2026-10-14.json), [initial401](ux-ui/acceptance/gre220-initial-native-failure-2026-10-14.json), [whole native/UI/cleanup](ux-ui/acceptance/gre220-native-live-2026-10-14.json). Следующий221 — отклонять missing/duplicate native GRE identity в каталоге/config snapshots; сейчас mapGreLive допускает выдуманные fallback IDs/names. + ## 12.5.219 — ошибки реального GRE source для snapshots (2026-10-14) fetchGreTunnelLiveRows подавлял native failures через[] и collector принимал пустой/неполный источник без ошибки. Теперь per-device reads settled независимо, все ошибки агрегируются по устройствам и неполный источник отклоняется; collector записывает GRE source error и сохраняет независимо прочитанный BGP. Raw GRE должен быть корректной коллекцией string records с native .id/name; duplicate IDs отклоняются. Правила сигналов/доставки и существующая трактовка running/disabled пока не менялись: неизвестные operational flags — следующий220. diff --git a/docs/ux-ui-remaining-acceptance.md b/docs/ux-ui-remaining-acceptance.md index 0a6c7f72..a69cec32 100644 --- a/docs/ux-ui-remaining-acceptance.md +++ b/docs/ux-ui-remaining-acceptance.md @@ -1,10 +1,10 @@ # Оставшаяся внешняя приёмка — 2026-10-13 -Актуальное продолжение 2026-10-14: блок219 завершён. GRE source snapshots больше не подавляет per-device ошибки; повреждённые records/duplicate native IDs отклоняются. BGP observations сохраняются при GRE failure. Четыре профиля, SQL/native10, compiled actual source2own GRE и UI1440/320 прошли; own DB/roles/tunnels удалены. Backend ux-gre219/compiled1052/source486 matched, frontend ux-routing218. Следующий220 — неизвестные/некорректные GRE operational flags в snapshots. Этап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 открыт. -Это актуальная матрица после 12.5.219. Исторические записи сохраняют версии и ограничения на момент выполнения; поздние проверки ниже уточняют их. Этап 12.5 открыт. Успех в двух CHR и одном backend не означает приёмку всех конфигураций, интеграций или полной регрессии. +Это актуальная матрица после 12.5.220. Исторические записи сохраняют версии и ограничения на момент выполнения; поздние проверки ниже уточняют их. Этап 12.5 открыт. Успех в двух CHR и одном backend не означает приёмку всех конфигураций, интеграций или полной регрессии. -Стенд: Debian13/Compose, PostgreSQL18.6, два CHR RouterOS7.24.5. Backend `ux-gre219`, frontend `ux-routing218`; production lab с195 использует AUTH_REQUIRED=true и Portal1.3.1. Подписанные JWT/RBAC проверялись в изолированных процессах. Все собственные объекты112 удалены, исходные13 коллекций×2 (включая logging/certificates/files/routes) проверены; пароли не менялись. +Стенд: Debian13/Compose, PostgreSQL18.6, два CHR RouterOS7.24.5. Backend `ux-gre220`, frontend `ux-routing218`; production lab с195 использует AUTH_REQUIRED=true и Portal1.3.1. Подписанные JWT/RBAC проверялись в изолированных процессах. Все собственные объекты112 удалены, исходные13 коллекций×2 (включая logging/certificates/files/routes) проверены; пароли не менялись. | Раздел | Подтверждено | Осталось / условие завершения | | --- | --- | --- | @@ -1521,3 +1521,7 @@ BGP/OSPF contrast: baseline22/fixed104 cells0 violations; E2E22 и real UI8 pass ## 12.5.219 — GRE snapshot source (2026-10-14) Ошибки GRE source отражаются в snapshot; BGP при GRE failure сохраняется. SQL/native10 и actual compiled source2own GRE/UI passed; временные объекты удалены. Подробности и границы — [журнал](ux-ui-progress.md). 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 сохранён, причина неизвестна. Подробности и границы — [журнал](ux-ui-progress.md). Backend ux-gre220, frontend ux-routing218; следующий221 — GRE identity guards. diff --git a/docs/ux-ui-stage-12.md b/docs/ux-ui-stage-12.md index 5ec5f170..0eef8277 100644 --- a/docs/ux-ui-stage-12.md +++ b/docs/ux-ui-stage-12.md @@ -1,6 +1,6 @@ # Этап 12: итоговая приёмка UX/UI -Актуальное продолжение 2026-10-14: блок219 завершён. GRE source snapshots больше не подавляет per-device ошибки; повреждённые records/duplicate native IDs отклоняются. BGP observations сохраняются при GRE failure. Четыре профиля, SQL/native10, compiled actual source2own GRE и UI1440/320 прошли; own DB/roles/tunnels удалены. Backend ux-gre219/compiled1052/source486 matched, frontend ux-routing218. Следующий220 — неизвестные/некорректные GRE operational flags в snapshots. Этап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 открыт. План: [ux-ui-plan.md](ux-ui-plan.md). Фактические результаты: [ux-ui-progress.md](ux-ui-progress.md). Подготовлен после сводных проверок 11Б; завершение каждого блока требует локального коммита без push. @@ -3978,3 +3978,16 @@ Backend ux-gre219 compiled1052/source486 matched, healthy; frontend ux-routing21 Протоколы: [baseline](ux-ui/acceptance/gre219-baseline.json), [fixed](ux-ui/acceptance/gre219-fixed.json), [build](ux-ui/acceptance/gre219-build-proof-2026-10-14.json), [deployment](ux-ui/acceptance/gre219-deployment-2026-10-14.json), [native source/UI/cleanup](ux-ui/acceptance/gre219-native-live-2026-10-14.json). Следующий220 — не подтверждать degraded/up/down по отсутствующим/повреждённым GRE flags; валидные native состояния сохранить. + +## 12.5.220 — подтверждённые operational flags GRE (2026-10-14) + +Общий readGreObservedState используется в live catalog/config snapshot и alert source. true/false/yes/no читаются одинаково; disabled=true подтверждает down независимо от running. При неизвестном disabled или running у enabled interface опрос устройства отклоняется. Достоверные up/down/degraded сохранены; главная API-envelope по-прежнему передаёт failures по устройствам, а source snapshot сообщает GRE error и сохраняет BGP. Unknown metadata больше не выдаётся за подтверждённый operational status. Другие параметры/defaults GRE этим блоком не объявляются полностью проверенными. + +Local49 комбинаций проверили оба reader пути. Профили live-maps14 и config-sync6, build прошли; optional SQL branch network-disabled-server без его специального env skipped, не считается новой SQL приёмкой. Первая IPv6 fixture имела running=true, но не имела disabled: дополнена explicit false, повтор passed. Baseline ux-gre219/fixed ux-gre220 по30 production checks:15 flags через compiled snapshot collector и signed reader GRE API. Unknown flags дают sourceError и per-device API failure; здоровое устройство остаётся в catalog. BGP2 control rows сохраняются. Own DB/roles удалены, native writes0. + +Backend ux-gre220 compiled1056/source488 matched, healthy; frontend ux-routing218 сохранён. Первая live попытка прервана native401104.165.244.7; точный failed request path не записан. Cleanup созданных own GRE сообщил успех. Шесть последующих native checks200 на обоих CHR с теми же credentials; root cause не установлен. Новый цельный run использовал Connection close в прямых контрольных REST calls; это не causal proof причины401 и не production auth retry. + +В повторном run own GRE2/IPv4inner поднялись up, Ping3/3 в обе стороны. Actual compiled collector read lab DB/native и подтвердил own up2/sourceErrors0 без scheduler history write. UI1440/320 показал own rows без page errors/mutations. Disable одного: native/API down + peer degraded; enable: recovery up/up и повторный Ping3/3 обоих. Own interfaces/addresses удалены, absence API/native проверен; пароли не менялись. Это controlled краткая loss/recovery, не physical WAN/SLA/длительная устойчивость. + +Протоколы: [baseline](ux-ui/acceptance/gre220-baseline.json), [fixed](ux-ui/acceptance/gre220-fixed.json), [build](ux-ui/acceptance/gre220-build-proof-2026-10-14.json), [deployment](ux-ui/acceptance/gre220-deployment-2026-10-14.json), [initial401](ux-ui/acceptance/gre220-initial-native-failure-2026-10-14.json), [whole native/UI/cleanup](ux-ui/acceptance/gre220-native-live-2026-10-14.json). Следующий221 — отклонять missing/duplicate native GRE identity в каталоге/config snapshots; сейчас mapGreLive допускает выдуманные fallback IDs/names. + diff --git a/docs/ux-ui-test-server.md b/docs/ux-ui-test-server.md index 9f1d9779..e422032b 100644 --- a/docs/ux-ui-test-server.md +++ b/docs/ux-ui-test-server.md @@ -1,6 +1,6 @@ # Тестовый сервер UX/UI — 2026-10-10 -Актуальное продолжение 2026-10-14: блок219 завершён. GRE source snapshots больше не подавляет per-device ошибки; повреждённые records/duplicate native IDs отклоняются. BGP observations сохраняются при GRE failure. Четыре профиля, SQL/native10, compiled actual source2own GRE и UI1440/320 прошли; own DB/roles/tunnels удалены. Backend ux-gre219/compiled1052/source486 matched, frontend ux-routing218. Следующий220 — неизвестные/некорректные GRE operational flags в snapshots. Этап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 открыт. | Параметр | Проверенное состояние | | --- | --- | @@ -2334,3 +2334,7 @@ BGP/OSPF contrast: baseline22/fixed104 cells0 violations; E2E22 и real UI8 pass ## 12.5.219 — GRE snapshot source (2026-10-14) Ошибки GRE source отражаются в snapshot; BGP при GRE failure сохраняется. SQL/native10 и actual compiled source2own GRE/UI passed; временные объекты удалены. Подробности и границы — [журнал](ux-ui-progress.md). 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 сохранён, причина неизвестна. Подробности и границы — [журнал](ux-ui-progress.md). Backend ux-gre220, frontend ux-routing218; следующий221 — GRE identity guards. diff --git a/docs/ux-ui/acceptance/gre220-baseline.json b/docs/ux-ui/acceptance/gre220-baseline.json new file mode 100644 index 00000000..ec066124 --- /dev/null +++ b/docs/ux-ui/acceptance/gre220-baseline.json @@ -0,0 +1,292 @@ +{ + "date": "2026-10-14", + "block": "12.5.220", + "baseline": true, + "database": "mm_accept_166_1791916058621", + "cases": [ + { + "phase": "up", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 2, + "failures": 0 + }, + { + "phase": "up", + "flags": { + "running": "true", + "disabled": "false" + }, + "greWritten": 2, + "bgpWritten": 2, + "sourceErrors": 0, + "secondStatus": "up", + "nativeCalls": 10 + }, + { + "phase": "degraded", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 2, + "failures": 0 + }, + { + "phase": "degraded", + "flags": { + "running": "false", + "disabled": "false" + }, + "greWritten": 2, + "bgpWritten": 2, + "sourceErrors": 0, + "secondStatus": "degraded", + "nativeCalls": 10 + }, + { + "phase": "down", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 2, + "failures": 0 + }, + { + "phase": "down", + "flags": { + "running": "false", + "disabled": "true" + }, + "greWritten": 2, + "bgpWritten": 2, + "sourceErrors": 0, + "secondStatus": "down", + "nativeCalls": 10 + }, + { + "phase": "yes-up", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 2, + "failures": 0 + }, + { + "phase": "yes-up", + "flags": { + "running": "yes", + "disabled": "no" + }, + "greWritten": 2, + "bgpWritten": 2, + "sourceErrors": 0, + "secondStatus": "degraded", + "nativeCalls": 10 + }, + { + "phase": "yes-degraded", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 2, + "failures": 0 + }, + { + "phase": "yes-degraded", + "flags": { + "running": "no", + "disabled": "no" + }, + "greWritten": 2, + "bgpWritten": 2, + "sourceErrors": 0, + "secondStatus": "degraded", + "nativeCalls": 10 + }, + { + "phase": "yes-down", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 2, + "failures": 0 + }, + { + "phase": "yes-down", + "flags": { + "running": "no", + "disabled": "yes" + }, + "greWritten": 2, + "bgpWritten": 2, + "sourceErrors": 0, + "secondStatus": "degraded", + "nativeCalls": 10 + }, + { + "phase": "missing-disabled", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 2, + "failures": 0 + }, + { + "phase": "missing-disabled", + "flags": { + "running": "true" + }, + "greWritten": 2, + "bgpWritten": 2, + "sourceErrors": 0, + "secondStatus": "up", + "nativeCalls": 10 + }, + { + "phase": "missing-running", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 2, + "failures": 0 + }, + { + "phase": "missing-running", + "flags": { + "disabled": "false" + }, + "greWritten": 2, + "bgpWritten": 2, + "sourceErrors": 0, + "secondStatus": "degraded", + "nativeCalls": 10 + }, + { + "phase": "blank-disabled", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 2, + "failures": 0 + }, + { + "phase": "blank-disabled", + "flags": { + "running": "true", + "disabled": "" + }, + "greWritten": 2, + "bgpWritten": 2, + "sourceErrors": 0, + "secondStatus": "up", + "nativeCalls": 10 + }, + { + "phase": "invalid-running", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 2, + "failures": 0 + }, + { + "phase": "invalid-running", + "flags": { + "running": "junk", + "disabled": "false" + }, + "greWritten": 2, + "bgpWritten": 2, + "sourceErrors": 0, + "secondStatus": "degraded", + "nativeCalls": 10 + }, + { + "phase": "invalid-disabled", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 2, + "failures": 0 + }, + { + "phase": "invalid-disabled", + "flags": { + "running": "true", + "disabled": "junk" + }, + "greWritten": 2, + "bgpWritten": 2, + "sourceErrors": 0, + "secondStatus": "up", + "nativeCalls": 10 + }, + { + "phase": "both-missing", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 2, + "failures": 0 + }, + { + "phase": "both-missing", + "flags": {}, + "greWritten": 2, + "bgpWritten": 2, + "sourceErrors": 0, + "secondStatus": "degraded", + "nativeCalls": 10 + }, + { + "phase": "disabled-missing-running", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 2, + "failures": 0 + }, + { + "phase": "disabled-missing-running", + "flags": { + "disabled": "true" + }, + "greWritten": 2, + "bgpWritten": 2, + "sourceErrors": 0, + "secondStatus": "down", + "nativeCalls": 10 + }, + { + "phase": "disabled-invalid-running", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 2, + "failures": 0 + }, + { + "phase": "disabled-invalid-running", + "flags": { + "disabled": "true", + "running": "junk" + }, + "greWritten": 2, + "bgpWritten": 2, + "sourceErrors": 0, + "secondStatus": "down", + "nativeCalls": 10 + }, + { + "phase": "recovery", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 2, + "failures": 0 + }, + { + "phase": "recovery", + "flags": { + "running": "true", + "disabled": "false" + }, + "greWritten": 2, + "bgpWritten": 2, + "sourceErrors": 0, + "secondStatus": "up", + "nativeCalls": 10 + } + ], + "scope": "Actual compiled GRE operational flags and actual snapshot collector, owned SQL/native HTTP fixture; signed reader/authenticated GRE API", + "passed": true, + "nativeWrites": 0, + "disabledHomeRouterCalls": 0, + "ownedDatabaseAndRoleRemoved": true +} diff --git a/docs/ux-ui/acceptance/gre220-build-proof-2026-10-14.json b/docs/ux-ui/acceptance/gre220-build-proof-2026-10-14.json new file mode 100644 index 00000000..15877ee2 --- /dev/null +++ b/docs/ux-ui/acceptance/gre220-build-proof-2026-10-14.json @@ -0,0 +1,23 @@ +{ + "date": "2026-10-14", + "block": "12.5.220", + "compiled": { + "matched": 1056, + "missing": 0, + "different": 0 + }, + "source": [ + { + "kind": "backend", + "matched": 488 + } + ], + "profileScripts": { + "liveMaps": 14, + "configSync": 6, + "greFlagCombinations": 49 + }, + "optionalDisabledSqlProfileSkipped": true, + "productionCases": 30, + "initialLocalFixtureFailure": "GRE IPv6 fixture omitted disabled; updated to explicit false, repeated configSync passed" +} diff --git a/docs/ux-ui/acceptance/gre220-deployment-2026-10-14.json b/docs/ux-ui/acceptance/gre220-deployment-2026-10-14.json new file mode 100644 index 00000000..31a06963 --- /dev/null +++ b/docs/ux-ui/acceptance/gre220-deployment-2026-10-14.json @@ -0,0 +1,21 @@ +{ + "date": "2026-10-14", + "block": "12.5.220", + "backendSourceMatched": 488, + "compiledMatched": 1056, + "frontendChanged": false, + "services": { + "backend": { + "image": "mmapp-test/backend:ux-gre220", + "imageId": "sha256:ccec71e8e2e1fd3a13e98be145cba26cdd2dc85409053e00e88d3ca81de5329d", + "running": true, + "health": "healthy" + }, + "frontend": { + "image": "mmapp-test/frontend:ux-routing218", + "imageId": "sha256:ec658b9da88c19d60987be5bfc0c15fb339a0310d7a42dc761b40a70a3428c5a", + "running": true, + "health": null + } + } +} diff --git a/docs/ux-ui/acceptance/gre220-fixed.json b/docs/ux-ui/acceptance/gre220-fixed.json new file mode 100644 index 00000000..990a89f0 --- /dev/null +++ b/docs/ux-ui/acceptance/gre220-fixed.json @@ -0,0 +1,292 @@ +{ + "date": "2026-10-14", + "block": "12.5.220", + "baseline": false, + "database": "mm_accept_166_1791916217951", + "cases": [ + { + "phase": "up", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 2, + "failures": 0 + }, + { + "phase": "up", + "flags": { + "running": "true", + "disabled": "false" + }, + "greWritten": 2, + "bgpWritten": 2, + "sourceErrors": 0, + "secondStatus": "up", + "nativeCalls": 10 + }, + { + "phase": "degraded", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 2, + "failures": 0 + }, + { + "phase": "degraded", + "flags": { + "running": "false", + "disabled": "false" + }, + "greWritten": 2, + "bgpWritten": 2, + "sourceErrors": 0, + "secondStatus": "degraded", + "nativeCalls": 10 + }, + { + "phase": "down", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 2, + "failures": 0 + }, + { + "phase": "down", + "flags": { + "running": "false", + "disabled": "true" + }, + "greWritten": 2, + "bgpWritten": 2, + "sourceErrors": 0, + "secondStatus": "down", + "nativeCalls": 10 + }, + { + "phase": "yes-up", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 2, + "failures": 0 + }, + { + "phase": "yes-up", + "flags": { + "running": "yes", + "disabled": "no" + }, + "greWritten": 2, + "bgpWritten": 2, + "sourceErrors": 0, + "secondStatus": "up", + "nativeCalls": 10 + }, + { + "phase": "yes-degraded", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 2, + "failures": 0 + }, + { + "phase": "yes-degraded", + "flags": { + "running": "no", + "disabled": "no" + }, + "greWritten": 2, + "bgpWritten": 2, + "sourceErrors": 0, + "secondStatus": "degraded", + "nativeCalls": 10 + }, + { + "phase": "yes-down", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 2, + "failures": 0 + }, + { + "phase": "yes-down", + "flags": { + "running": "no", + "disabled": "yes" + }, + "greWritten": 2, + "bgpWritten": 2, + "sourceErrors": 0, + "secondStatus": "down", + "nativeCalls": 10 + }, + { + "phase": "missing-disabled", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 1, + "failures": 1 + }, + { + "phase": "missing-disabled", + "flags": { + "running": "true" + }, + "greWritten": 0, + "bgpWritten": 2, + "sourceErrors": 1, + "secondStatus": null, + "nativeCalls": 10 + }, + { + "phase": "missing-running", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 1, + "failures": 1 + }, + { + "phase": "missing-running", + "flags": { + "disabled": "false" + }, + "greWritten": 0, + "bgpWritten": 2, + "sourceErrors": 1, + "secondStatus": null, + "nativeCalls": 10 + }, + { + "phase": "blank-disabled", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 1, + "failures": 1 + }, + { + "phase": "blank-disabled", + "flags": { + "running": "true", + "disabled": "" + }, + "greWritten": 0, + "bgpWritten": 2, + "sourceErrors": 1, + "secondStatus": null, + "nativeCalls": 10 + }, + { + "phase": "invalid-running", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 1, + "failures": 1 + }, + { + "phase": "invalid-running", + "flags": { + "running": "junk", + "disabled": "false" + }, + "greWritten": 0, + "bgpWritten": 2, + "sourceErrors": 1, + "secondStatus": null, + "nativeCalls": 10 + }, + { + "phase": "invalid-disabled", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 1, + "failures": 1 + }, + { + "phase": "invalid-disabled", + "flags": { + "running": "true", + "disabled": "junk" + }, + "greWritten": 0, + "bgpWritten": 2, + "sourceErrors": 1, + "secondStatus": null, + "nativeCalls": 10 + }, + { + "phase": "both-missing", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 1, + "failures": 1 + }, + { + "phase": "both-missing", + "flags": {}, + "greWritten": 0, + "bgpWritten": 2, + "sourceErrors": 1, + "secondStatus": null, + "nativeCalls": 10 + }, + { + "phase": "disabled-missing-running", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 2, + "failures": 0 + }, + { + "phase": "disabled-missing-running", + "flags": { + "disabled": "true" + }, + "greWritten": 2, + "bgpWritten": 2, + "sourceErrors": 0, + "secondStatus": "down", + "nativeCalls": 10 + }, + { + "phase": "disabled-invalid-running", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 2, + "failures": 0 + }, + { + "phase": "disabled-invalid-running", + "flags": { + "disabled": "true", + "running": "junk" + }, + "greWritten": 2, + "bgpWritten": 2, + "sourceErrors": 0, + "secondStatus": "down", + "nativeCalls": 10 + }, + { + "phase": "recovery", + "endpoint": "GRE authenticated catalog", + "status": 200, + "tunnels": 2, + "failures": 0 + }, + { + "phase": "recovery", + "flags": { + "running": "true", + "disabled": "false" + }, + "greWritten": 2, + "bgpWritten": 2, + "sourceErrors": 0, + "secondStatus": "up", + "nativeCalls": 10 + } + ], + "scope": "Actual compiled GRE operational flags and actual snapshot collector, owned SQL/native HTTP fixture; signed reader/authenticated GRE API", + "passed": true, + "nativeWrites": 0, + "disabledHomeRouterCalls": 0, + "ownedDatabaseAndRoleRemoved": true +} diff --git a/docs/ux-ui/acceptance/gre220-initial-native-failure-2026-10-14.json b/docs/ux-ui/acceptance/gre220-initial-native-failure-2026-10-14.json new file mode 100644 index 00000000..a9518e57 --- /dev/null +++ b/docs/ux-ui/acceptance/gre220-initial-native-failure-2026-10-14.json @@ -0,0 +1,47 @@ +{ + "date": "2026-10-14", + "block": "12.5.220", + "host": "104.165.244.7", + "status": 401, + "failedRequestPathNotRecorded": true, + "wholeLiveAttemptAborted": true, + "ownedGreCleanupReported": true, + "causeKnown": false, + "subsequentAccessCheck": { + "date": "2026-10-14", + "cases": [ + { + "host": "194.226.121.150", + "path": "/system/resource", + "status": 200 + }, + { + "host": "194.226.121.150", + "path": "/ip/address", + "status": 200 + }, + { + "host": "194.226.121.150", + "path": "/interface/gre", + "status": 200 + }, + { + "host": "104.165.244.7", + "path": "/system/resource", + "status": 200 + }, + { + "host": "104.165.244.7", + "path": "/ip/address", + "status": 200 + }, + { + "host": "104.165.244.7", + "path": "/interface/gre", + "status": 200 + } + ] + }, + "probeDifference": "Independent recheck uses Connection close; no causal claim", + "passwordsNotChanged": true +} diff --git a/docs/ux-ui/acceptance/gre220-native-live-2026-10-14.json b/docs/ux-ui/acceptance/gre220-native-live-2026-10-14.json new file mode 100644 index 00000000..1fe79e32 --- /dev/null +++ b/docs/ux-ui/acceptance/gre220-native-live-2026-10-14.json @@ -0,0 +1,100 @@ +{ + "date": "2026-10-14", + "block": "12.5.220", + "backend": "ux-gre220", + "frontend": "ux-routing218", + "nativeCases": [ + { + "host": "194.226.121.150", + "nativeGetStatus": 200, + "applicationStatus": "degraded", + "nativeDisabled": "false", + "nativeRunning": "false", + "nativeIdPresent": true, + "nativeNamePresent": true + }, + { + "host": "104.165.244.7", + "nativeGetStatus": 200, + "applicationStatus": "degraded", + "nativeDisabled": "false", + "nativeRunning": "false", + "nativeIdPresent": true, + "nativeNamePresent": true + } + ], + "source": { + "date": "2026-10-14", + "name": "own220-gre-1791916454934", + "passed": true, + "mode": "Actual compiled helper reads lab PostgreSQL/native enabled GRE and BGP; no scheduler history write", + "ownedGreRows": [ + { + "targetLabel": "own220-gre-1791916454934-1 / CHR", + "status": "up" + }, + { + "targetLabel": "own220-gre-1791916454934-2 / CHR", + "status": "up" + } + ], + "sourceErrors": 0 + }, + "ui": [ + { + "width": 1440, + "ownedNativeRowVisible": true, + "pageErrors": 0, + "mutationRequests": 0 + }, + { + "width": 320, + "ownedNativeRowVisible": true, + "pageErrors": 0, + "mutationRequests": 0 + } + ], + "transitions": [ + { + "phase": "both-up", + "nativeFlagsConfirmed": true, + "ping": [ + { + "host": "194.226.121.150", + "received": 3 + }, + { + "host": "104.165.244.7", + "received": 3 + } + ] + }, + { + "phase": "one-disabled-peer-degraded", + "nativeFlagsConfirmed": true, + "applicationStatuses": [ + "down", + "degraded" + ] + }, + { + "phase": "recovered-up", + "nativeFlagsConfirmed": true, + "ping": [ + { + "host": "194.226.121.150", + "received": 3 + }, + { + "host": "104.165.244.7", + "received": 3 + } + ] + } + ], + "realPortalJWT": true, + "apiMocks": false, + "cleanupCompleted": true, + "scope": "Actual compiled collector and API read confirmed GRE flags; controlled peer disable/recovery and short IPv4 Ping; no physical WAN loss/SLA or durable snapshot write", + "passwordsUnchanged": true +}