diff --git a/deploy/TEST-ACME.md b/deploy/TEST-ACME.md
index 48ba9aeb..3933ac70 100644
--- a/deploy/TEST-ACME.md
+++ b/deploy/TEST-ACME.md
@@ -39,3 +39,7 @@
Следующий реальный тест259: активировать подготовленный образ258, снять свежий baseline и выполнить согласованный first issue + scheduler renewal. Проверить ровно один leaf с логическим именем, один архив старого leaf с прежними ID/SHA-256/private-key и отсутствие незавершённых `_new_` объектов. Trusted TLS должен совпасть с новым leaf; canonical dates — с X509. Очистка должна учитывать собственные `_old_`/`_new_` имена с12hex, exact CN и записанные ID/fingerprints. Старый cleanup helper256, допускавший лишь exact logical/root имена, без адаптации не запускать. Удалять leaf поколения до собственных CA, затем проверить отсутствие и исходный export/files/services/settings. Чужие объекты не удалять.
Образ258 подготовлен и проверен локальными service сценариями; до этого реального теста активный backend остаётся257. Повторное согласование того же уже разрешённого сценария не требуется. Продление не объявляется принятым по fixtures.
+
+## Реальная ротация принята — блок259 (2026-10-15)
+
+First issue через настоящий Portal/UI и одно enable-triggered scheduler renewal того же exact домена завершены. Новый native ID/SHA-256, единственный logical name, один old archive с прежними ID/fingerprint/private-key и отсутствие unfinished new подтверждены. Оба trusted TLS samples совпали с соответствующими native leaf, отпечаток изменился; HTTPS REST200 после продления. Native/SSL/files/export/private SQL/DNS восстановлены, оба CHR доступны, private baseline/fixtures удалены. Активен backend258/frontend251. CA revocation не выполнялся. Протоколы находятся в docs/ux-ui/acceptance/acme259-*.json; следующий запуск требует свежего baseline, удалённый259 повторно не использовать.
diff --git a/docs/ux-ui-external-acceptance.md b/docs/ux-ui-external-acceptance.md
index afb0916a..a508c84b 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-15: 258 — реализована unique generation rotation с проверкой нового leaf/SSL до архивации старого, сохранением прежнего ключа и финальным logical name. Profile9/build/lint passed, image ux-certificates258 source530/dist1084 prepared, ещё не активирован; runtime backend257/frontend251. Следующий259 — согласованный real first issue + scheduler renewal, trusted TLS, unique logical name/old archive и полный откат; разрешение сохраняется. Этап12.5 открыт.
+Актуальное продолжение 2026-10-15: 259 — реальный first issue и scheduler renewal приняты: trusted TLS сменил SHA-256, один logical leaf, старые native ID/fingerprint/private-key сохранены в архиве. Native/export/SSL/SQL/DNS восстановлены, private fixtures удалены. Runtime backend258/frontend251 healthy. Следующий260 — актуализировать остаток и выполнить профильную приёмку UX/доступности/производительности; этап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).
@@ -18,6 +18,20 @@ OSPF84: real GRE Full adjacency/private routes/Ping3/3 и4 live PC/320px URL/bro
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 без новой сборки. [Отчёт](ux-ui/acceptance/ospf-bfd-loss-2026-10-09.json).
+## 12.5.259 — реальная ротация сертификата и подтверждённый откат (2026-10-15)
+
+По сохранённому разрешению254 выполнен тот же exact mmt253-8e62a941.pngs.top на104.165.244.7. Перед началом снят свежий приватный native/export/SSL/files/SQL baseline; own certificate/files/jobs/DNS0, Cloudflare token/zone/account проверены. Renewal временно выключен. Подготовленный backend258 активирован; frontend251/Portal/DB сохранены, backend healthy. [Развёртывание](ux-ui/acceptance/acme259-deployment.json).
+
+Настоящий Portal/UI без mocks: один manual issue POST, terminal done, JS errors0. Native logical leaf единственный, private-key=true, обе SSL службы enabled с logical name. Независимый trusted TLS/SNI/hostname совпал с native SHA-256. [UI](ux-ui/acceptance/acme259-live-ui.json), [первый TLS](ux-ui/acceptance/acme259-tls-before.json).
+
+Один PUT enabled=true запустил штатный certificates_renew; отдельный run-now0. Canonical validity распознан, daysLeft90; revocationStatusunknown не подменяется valid. Единственная цель, scheduler ok/renewed1/errors0, затем renewal сразу disabled. Реальный цикл31.488s — не гарантия длительности следующих выдач. [Планировщик](ux-ui/acceptance/acme259-renewal.json).
+
+После продления native logical name ровно1, unfinished _new_0; прежний leaf сохранён в одном _old_<12hex> с теми же ID/SHA-256/private-key. Новый ID и SHA-256 отличаются. Trusted TLS обслуживает новый leaf, canonical validFrom/validUntil совпадают с X509; обычный HTTPS REST200 после продления. [Ротация](ux-ui/acceptance/acme259-native-rotation.json), [новый TLS](ux-ui/acceptance/acme259-tls-after.json), [сравнение](ux-ui/acceptance/acme259-tls-comparison.json). Это успешная конкретная последовательная ротация двух SSL служб; zero-downtime, другие потребители старого ключа и несколько issuers не заявляются.
+
+Очистка: SSL baseline → только собственные поколения/CA/files → два own terminal jobs → исходные ACME/renew settings целиком. Приложение удалило TXT; собственная A удалена по exact ID/name/type/content, оба DNS имени0. После scheduler refresh повторно восстановлены исходные SQL timestamps/meta. Native certificates/files/SSL, normalized export и приватные SQL строки совпали; при сравнении files исключён last-modified, export — комментарии/пустые строки. Private baseline/key fixtures удалены на Debian и локально. Оба CHR доступны, пароли не менялись. [Откат](ux-ui/acceptance/acme259-cleanup.json), [DNS](ux-ui/acceptance/acme259-cloudflare.json).
+
+В ручном helper SQL count оказался number0, не string0: первая проверка restore остановилась до device writes, тип ожидания исправлен. Диагностический SELECT с несуществующим created_at отклонён без записей. Эти ошибки приёмочного кода не скрыты и не считаются дефектами продукта. Для неизменённого production кода build/profile не повторялись:258 уже проверен9 scripts/build/lint, общая transport regression257 —25 profiles. CA revocation не выполнен; удаление native сертификата не означает отзыв CA. Следующий260 — актуальный остаток и профильный UX/a11y/performance контроль.
+
## 12.5.258 — уникальное новое поколение и сохранение старого сертификата (2026-10-15)
После256/257 issuer проверяет duplicate logical name ещё до CA order. Leaf/key получают случайное уникальное имя _new_<12hex>, signed X509 fingerprint вычисляется до native upload. rotateCertificateGeneration требует подтверждённые разные native IDs и свободное archive name; сначала проверяет новый leaf/private-key и назначения обоих SSL сервисов на него. Только после этого прежний logical объект переносится в _old_<12hex>, новый получает прежнее logical name и повторно проверяются fingerprint/private-key/services. Старый объект/ключ не удаляется, данные jobs/requestId остаются совместимыми.
diff --git a/docs/ux-ui-plan.md b/docs/ux-ui-plan.md
index 4706bc3d..b35a8861 100644
--- a/docs/ux-ui-plan.md
+++ b/docs/ux-ui-plan.md
@@ -1,9 +1,23 @@
# План реализации UX/UI по пятичасовым окнам
-Актуальное продолжение 2026-10-15: 258 — реализована unique generation rotation с проверкой нового leaf/SSL до архивации старого, сохранением прежнего ключа и финальным logical name. Profile9/build/lint passed, image ux-certificates258 source530/dist1084 prepared, ещё не активирован; runtime backend257/frontend251. Следующий259 — согласованный real first issue + scheduler renewal, trusted TLS, unique logical name/old archive и полный откат; разрешение сохраняется. Этап12.5 открыт.
+Актуальное продолжение 2026-10-15: 259 — реальный first issue и scheduler renewal приняты: trusted TLS сменил SHA-256, один logical leaf, старые native ID/fingerprint/private-key сохранены в архиве. Native/export/SSL/SQL/DNS восстановлены, private fixtures удалены. Runtime backend258/frontend251 healthy. Следующий260 — актуализировать остаток и выполнить профильную приёмку UX/доступности/производительности; этап12.5 открыт.
Общий план проекта MikrotikManager. Основан на согласованном плане из задачи; точка продолжения обновлена 2026-10-14. Источник фактического прогресса, проверок и ограничений — [журнал реализации](ux-ui-progress.md). Этот документ задаёт объём и критерии завершения, журнал фиксирует результат.
+## 12.5.259 — реальная ротация сертификата и подтверждённый откат (2026-10-15)
+
+По сохранённому разрешению254 выполнен тот же exact mmt253-8e62a941.pngs.top на104.165.244.7. Перед началом снят свежий приватный native/export/SSL/files/SQL baseline; own certificate/files/jobs/DNS0, Cloudflare token/zone/account проверены. Renewal временно выключен. Подготовленный backend258 активирован; frontend251/Portal/DB сохранены, backend healthy. [Развёртывание](ux-ui/acceptance/acme259-deployment.json).
+
+Настоящий Portal/UI без mocks: один manual issue POST, terminal done, JS errors0. Native logical leaf единственный, private-key=true, обе SSL службы enabled с logical name. Независимый trusted TLS/SNI/hostname совпал с native SHA-256. [UI](ux-ui/acceptance/acme259-live-ui.json), [первый TLS](ux-ui/acceptance/acme259-tls-before.json).
+
+Один PUT enabled=true запустил штатный certificates_renew; отдельный run-now0. Canonical validity распознан, daysLeft90; revocationStatusunknown не подменяется valid. Единственная цель, scheduler ok/renewed1/errors0, затем renewal сразу disabled. Реальный цикл31.488s — не гарантия длительности следующих выдач. [Планировщик](ux-ui/acceptance/acme259-renewal.json).
+
+После продления native logical name ровно1, unfinished _new_0; прежний leaf сохранён в одном _old_<12hex> с теми же ID/SHA-256/private-key. Новый ID и SHA-256 отличаются. Trusted TLS обслуживает новый leaf, canonical validFrom/validUntil совпадают с X509; обычный HTTPS REST200 после продления. [Ротация](ux-ui/acceptance/acme259-native-rotation.json), [новый TLS](ux-ui/acceptance/acme259-tls-after.json), [сравнение](ux-ui/acceptance/acme259-tls-comparison.json). Это успешная конкретная последовательная ротация двух SSL служб; zero-downtime, другие потребители старого ключа и несколько issuers не заявляются.
+
+Очистка: SSL baseline → только собственные поколения/CA/files → два own terminal jobs → исходные ACME/renew settings целиком. Приложение удалило TXT; собственная A удалена по exact ID/name/type/content, оба DNS имени0. После scheduler refresh повторно восстановлены исходные SQL timestamps/meta. Native certificates/files/SSL, normalized export и приватные SQL строки совпали; при сравнении files исключён last-modified, export — комментарии/пустые строки. Private baseline/key fixtures удалены на Debian и локально. Оба CHR доступны, пароли не менялись. [Откат](ux-ui/acceptance/acme259-cleanup.json), [DNS](ux-ui/acceptance/acme259-cloudflare.json).
+
+В ручном helper SQL count оказался number0, не string0: первая проверка restore остановилась до device writes, тип ожидания исправлен. Диагностический SELECT с несуществующим created_at отклонён без записей. Эти ошибки приёмочного кода не скрыты и не считаются дефектами продукта. Для неизменённого production кода build/profile не повторялись:258 уже проверен9 scripts/build/lint, общая transport regression257 —25 profiles. CA revocation не выполнен; удаление native сертификата не означает отзыв CA. Следующий260 — актуальный остаток и профильный UX/a11y/performance контроль.
+
## 12.5.258 — уникальное новое поколение и сохранение старого сертификата (2026-10-15)
После256/257 issuer проверяет duplicate logical name ещё до CA order. Leaf/key получают случайное уникальное имя _new_<12hex>, signed X509 fingerprint вычисляется до native upload. rotateCertificateGeneration требует подтверждённые разные native IDs и свободное archive name; сначала проверяет новый leaf/private-key и назначения обоих SSL сервисов на него. Только после этого прежний logical объект переносится в _old_<12hex>, новый получает прежнее logical name и повторно проверяются fingerprint/private-key/services. Старый объект/ключ не удаляется, данные jobs/requestId остаются совместимыми.
diff --git a/docs/ux-ui-progress.md b/docs/ux-ui-progress.md
index 7d4f2875..bc79ae33 100644
--- a/docs/ux-ui-progress.md
+++ b/docs/ux-ui-progress.md
@@ -1,6 +1,6 @@
# UX/UI: журнал реализации
-Актуальное продолжение 2026-10-15: 258 — реализована unique generation rotation с проверкой нового leaf/SSL до архивации старого, сохранением прежнего ключа и финальным logical name. Profile9/build/lint passed, image ux-certificates258 source530/dist1084 prepared, ещё не активирован; runtime backend257/frontend251. Следующий259 — согласованный real first issue + scheduler renewal, trusted TLS, unique logical name/old archive и полный откат; разрешение сохраняется. Этап12.5 открыт.
+Актуальное продолжение 2026-10-15: 259 — реальный first issue и scheduler renewal приняты: trusted TLS сменил SHA-256, один logical leaf, старые native ID/fingerprint/private-key сохранены в архиве. Native/export/SSL/SQL/DNS восстановлены, private fixtures удалены. Runtime backend258/frontend251 healthy. Следующий260 — актуализировать остаток и выполнить профильную приёмку UX/доступности/производительности; этап12.5 открыт.
Общий план: [UX/UI по этапам и пятичасовым окнам](ux-ui-plan.md). План задаёт объём, этот журнал фиксирует выполненные блоки и ограничения. Записи расположены от новых к старым; подробная история этапа12 также сохранена в [ux-ui-stage-12.md](ux-ui-stage-12.md).
@@ -36,7 +36,21 @@
| 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–258 в записанных scopes; unique rotation258 подготовлена, native acceptance259 остаётся открытой в записанных scopes. Runtime backend ux-certificates257/frontend ux-certificates251. Общая регрессия257 и профиль сертификатов252 прошли; реальный renewal остаётся открытым. |
+| 12 | Итоговая доступность, адаптивность, производительность и регрессия | Локальная12.3.83; внешняя12.5 открыта, блоки1–259 в записанных границах. Реальная ротация/renewal259 и полный откат приняты. Runtime backend ux-certificates258/frontend ux-certificates251. Общая backend-регрессия257 и профиль сертификатов258 прошли. Следующий260 — актуальный остаток и профильная итоговая приёмка. |
+
+## 12.5.259 — реальная ротация сертификата и подтверждённый откат (2026-10-15)
+
+По сохранённому разрешению254 выполнен тот же exact mmt253-8e62a941.pngs.top на104.165.244.7. Перед началом снят свежий приватный native/export/SSL/files/SQL baseline; own certificate/files/jobs/DNS0, Cloudflare token/zone/account проверены. Renewal временно выключен. Подготовленный backend258 активирован; frontend251/Portal/DB сохранены, backend healthy. [Развёртывание](ux-ui/acceptance/acme259-deployment.json).
+
+Настоящий Portal/UI без mocks: один manual issue POST, terminal done, JS errors0. Native logical leaf единственный, private-key=true, обе SSL службы enabled с logical name. Независимый trusted TLS/SNI/hostname совпал с native SHA-256. [UI](ux-ui/acceptance/acme259-live-ui.json), [первый TLS](ux-ui/acceptance/acme259-tls-before.json).
+
+Один PUT enabled=true запустил штатный certificates_renew; отдельный run-now0. Canonical validity распознан, daysLeft90; revocationStatusunknown не подменяется valid. Единственная цель, scheduler ok/renewed1/errors0, затем renewal сразу disabled. Реальный цикл31.488s — не гарантия длительности следующих выдач. [Планировщик](ux-ui/acceptance/acme259-renewal.json).
+
+После продления native logical name ровно1, unfinished _new_0; прежний leaf сохранён в одном _old_<12hex> с теми же ID/SHA-256/private-key. Новый ID и SHA-256 отличаются. Trusted TLS обслуживает новый leaf, canonical validFrom/validUntil совпадают с X509; обычный HTTPS REST200 после продления. [Ротация](ux-ui/acceptance/acme259-native-rotation.json), [новый TLS](ux-ui/acceptance/acme259-tls-after.json), [сравнение](ux-ui/acceptance/acme259-tls-comparison.json). Это успешная конкретная последовательная ротация двух SSL служб; zero-downtime, другие потребители старого ключа и несколько issuers не заявляются.
+
+Очистка: SSL baseline → только собственные поколения/CA/files → два own terminal jobs → исходные ACME/renew settings целиком. Приложение удалило TXT; собственная A удалена по exact ID/name/type/content, оба DNS имени0. После scheduler refresh повторно восстановлены исходные SQL timestamps/meta. Native certificates/files/SSL, normalized export и приватные SQL строки совпали; при сравнении files исключён last-modified, export — комментарии/пустые строки. Private baseline/key fixtures удалены на Debian и локально. Оба CHR доступны, пароли не менялись. [Откат](ux-ui/acceptance/acme259-cleanup.json), [DNS](ux-ui/acceptance/acme259-cloudflare.json).
+
+В ручном helper SQL count оказался number0, не string0: первая проверка restore остановилась до device writes, тип ожидания исправлен. Диагностический SELECT с несуществующим created_at отклонён без записей. Эти ошибки приёмочного кода не скрыты и не считаются дефектами продукта. Для неизменённого production кода build/profile не повторялись:258 уже проверен9 scripts/build/lint, общая transport regression257 —25 profiles. CA revocation не выполнен; удаление native сертификата не означает отзыв CA. Следующий260 — актуальный остаток и профильный UX/a11y/performance контроль.
## 12.5.258 — уникальное новое поколение и сохранение старого сертификата (2026-10-15)
diff --git a/docs/ux-ui-remaining-acceptance.md b/docs/ux-ui-remaining-acceptance.md
index be9ca911..596ef729 100644
--- a/docs/ux-ui-remaining-acceptance.md
+++ b/docs/ux-ui-remaining-acceptance.md
@@ -1,10 +1,24 @@
# Оставшаяся внешняя приёмка — 2026-10-14
-Актуальное продолжение 2026-10-15: 258 — реализована unique generation rotation с проверкой нового leaf/SSL до архивации старого, сохранением прежнего ключа и финальным logical name. Profile9/build/lint passed, image ux-certificates258 source530/dist1084 prepared, ещё не активирован; runtime backend257/frontend251. Следующий259 — согласованный real first issue + scheduler renewal, trusted TLS, unique logical name/old archive и полный откат; разрешение сохраняется. Этап12.5 открыт.
+Актуальное продолжение 2026-10-15: 259 — реальный first issue и scheduler renewal приняты: trusted TLS сменил SHA-256, один logical leaf, старые native ID/fingerprint/private-key сохранены в архиве. Native/export/SSL/SQL/DNS восстановлены, private fixtures удалены. Runtime backend258/frontend251 healthy. Следующий260 — актуализировать остаток и выполнить профильную приёмку UX/доступности/производительности; этап12.5 открыт.
-Это актуальная матрица после 12.5.258. Исторические записи сохраняют версии и ограничения на момент выполнения; поздние проверки ниже уточняют их. Этап 12.5 открыт. Успех в двух CHR и одном backend не означает приёмку всех конфигураций, интеграций или полной регрессии.
+Это актуальная матрица после 12.5.259. Исторические записи сохраняют версии и ограничения на момент выполнения; поздние проверки ниже уточняют их. Этап 12.5 открыт. Успех в двух CHR и одном backend не означает приёмку всех конфигураций, интеграций или полной регрессии.
-Стенд: Debian13/Compose, PostgreSQL18.6, два CHR RouterOS7.24.5. Backend `ux-certificates257`, frontend `ux-certificates251`; 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-certificates258`, frontend `ux-certificates251`; production lab с195 использует AUTH_REQUIRED=true и Portal1.3.1. Подписанные JWT/RBAC проверялись в изолированных процессах. Все собственные объекты112 удалены, исходные13 коллекций×2 (включая logging/certificates/files/routes) проверены; пароли не менялись.
+
+## 12.5.259 — реальная ротация сертификата и подтверждённый откат (2026-10-15)
+
+По сохранённому разрешению254 выполнен тот же exact mmt253-8e62a941.pngs.top на104.165.244.7. Перед началом снят свежий приватный native/export/SSL/files/SQL baseline; own certificate/files/jobs/DNS0, Cloudflare token/zone/account проверены. Renewal временно выключен. Подготовленный backend258 активирован; frontend251/Portal/DB сохранены, backend healthy. [Развёртывание](ux-ui/acceptance/acme259-deployment.json).
+
+Настоящий Portal/UI без mocks: один manual issue POST, terminal done, JS errors0. Native logical leaf единственный, private-key=true, обе SSL службы enabled с logical name. Независимый trusted TLS/SNI/hostname совпал с native SHA-256. [UI](ux-ui/acceptance/acme259-live-ui.json), [первый TLS](ux-ui/acceptance/acme259-tls-before.json).
+
+Один PUT enabled=true запустил штатный certificates_renew; отдельный run-now0. Canonical validity распознан, daysLeft90; revocationStatusunknown не подменяется valid. Единственная цель, scheduler ok/renewed1/errors0, затем renewal сразу disabled. Реальный цикл31.488s — не гарантия длительности следующих выдач. [Планировщик](ux-ui/acceptance/acme259-renewal.json).
+
+После продления native logical name ровно1, unfinished _new_0; прежний leaf сохранён в одном _old_<12hex> с теми же ID/SHA-256/private-key. Новый ID и SHA-256 отличаются. Trusted TLS обслуживает новый leaf, canonical validFrom/validUntil совпадают с X509; обычный HTTPS REST200 после продления. [Ротация](ux-ui/acceptance/acme259-native-rotation.json), [новый TLS](ux-ui/acceptance/acme259-tls-after.json), [сравнение](ux-ui/acceptance/acme259-tls-comparison.json). Это успешная конкретная последовательная ротация двух SSL служб; zero-downtime, другие потребители старого ключа и несколько issuers не заявляются.
+
+Очистка: SSL baseline → только собственные поколения/CA/files → два own terminal jobs → исходные ACME/renew settings целиком. Приложение удалило TXT; собственная A удалена по exact ID/name/type/content, оба DNS имени0. После scheduler refresh повторно восстановлены исходные SQL timestamps/meta. Native certificates/files/SSL, normalized export и приватные SQL строки совпали; при сравнении files исключён last-modified, export — комментарии/пустые строки. Private baseline/key fixtures удалены на Debian и локально. Оба CHR доступны, пароли не менялись. [Откат](ux-ui/acceptance/acme259-cleanup.json), [DNS](ux-ui/acceptance/acme259-cloudflare.json).
+
+В ручном helper SQL count оказался number0, не string0: первая проверка restore остановилась до device writes, тип ожидания исправлен. Диагностический SELECT с несуществующим created_at отклонён без записей. Эти ошибки приёмочного кода не скрыты и не считаются дефектами продукта. Для неизменённого production кода build/profile не повторялись:258 уже проверен9 scripts/build/lint, общая transport regression257 —25 profiles. CA revocation не выполнен; удаление native сертификата не означает отзыв CA. Следующий260 — актуальный остаток и профильный UX/a11y/performance контроль.
## 12.5.258 — уникальное новое поколение и сохранение старого сертификата (2026-10-15)
@@ -338,7 +352,7 @@ Portal offline JWT действует доexp после logout/role change; э
## Следующая последовательность — 2026-10-14
-1. **Сертификаты259:** unique generation rotation258/local checks/image готовы; activate258 + real first issue/renewal/TLS/archive/cleanup по сохранённому разрешению254. Active runtime257.
+1. **Приёмка260:** обновить актуальный остаток без устаревших blockers; профильный UX/a11y/performance контроль текущего runtime. Реальная ротация и откат259 приняты.
2. **Профильный контроль:** для новых изменений выполнять затронутые SQL/API/UI проверки. Общая регрессия192 выполнена; не повторять её без изменений общей основы или нового основания.
3. **Внешние зависимости:** Portal issuer/login/revoke, Telegram bot/chat/разрешённое сообщение, клиентские ОС, независимые WAN/public IPv6 и scale/multi-instance — отдельные группы по таблице выше. Ограничения текущего стенда не превращать в обещание приёмки всех конфигураций.
diff --git a/docs/ux-ui-stage-12.md b/docs/ux-ui-stage-12.md
index a3a29172..a4cabb6f 100644
--- a/docs/ux-ui-stage-12.md
+++ b/docs/ux-ui-stage-12.md
@@ -1,6 +1,6 @@
# Этап 12: итоговая приёмка UX/UI
-Актуальное продолжение 2026-10-15: 258 — реализована unique generation rotation с проверкой нового leaf/SSL до архивации старого, сохранением прежнего ключа и финальным logical name. Profile9/build/lint passed, image ux-certificates258 source530/dist1084 prepared, ещё не активирован; runtime backend257/frontend251. Следующий259 — согласованный real first issue + scheduler renewal, trusted TLS, unique logical name/old archive и полный откат; разрешение сохраняется. Этап12.5 открыт.
+Актуальное продолжение 2026-10-15: 259 — реальный first issue и scheduler renewal приняты: trusted TLS сменил SHA-256, один logical leaf, старые native ID/fingerprint/private-key сохранены в архиве. Native/export/SSL/SQL/DNS восстановлены, private fixtures удалены. Runtime backend258/frontend251 healthy. Следующий260 — актуализировать остаток и выполнить профильную приёмку UX/доступности/производительности; этап12.5 открыт.
План: [ux-ui-plan.md](ux-ui-plan.md). Фактические результаты: [ux-ui-progress.md](ux-ui-progress.md). Подготовлен после сводных проверок 11Б; завершение каждого блока требует локального коммита без push.
@@ -4152,6 +4152,20 @@ Real Portal/browser API, provider local verified: создан один job ро
Runtime backend ux-backup234/frontend ux-routing218 healthy; новое application image для volume-only fix не требовалось. Пароли CHR не менялись, S3 mutations0 в235, configs body/JWT не опубликованы, private local manifest удалён. Исходные10 missing local files не восстановлены и records не удалены. Force-recreate — не host reboot/power loss/fsync/DR приёмка. Далее236 — UX недоступных local files, затем version retention границы и оставшиеся7 группы матрицы; multi-instance guard не принимается. Этап12.5 открыт.
+## 12.5.259 — реальная ротация сертификата и подтверждённый откат (2026-10-15)
+
+По сохранённому разрешению254 выполнен тот же exact mmt253-8e62a941.pngs.top на104.165.244.7. Перед началом снят свежий приватный native/export/SSL/files/SQL baseline; own certificate/files/jobs/DNS0, Cloudflare token/zone/account проверены. Renewal временно выключен. Подготовленный backend258 активирован; frontend251/Portal/DB сохранены, backend healthy. [Развёртывание](ux-ui/acceptance/acme259-deployment.json).
+
+Настоящий Portal/UI без mocks: один manual issue POST, terminal done, JS errors0. Native logical leaf единственный, private-key=true, обе SSL службы enabled с logical name. Независимый trusted TLS/SNI/hostname совпал с native SHA-256. [UI](ux-ui/acceptance/acme259-live-ui.json), [первый TLS](ux-ui/acceptance/acme259-tls-before.json).
+
+Один PUT enabled=true запустил штатный certificates_renew; отдельный run-now0. Canonical validity распознан, daysLeft90; revocationStatusunknown не подменяется valid. Единственная цель, scheduler ok/renewed1/errors0, затем renewal сразу disabled. Реальный цикл31.488s — не гарантия длительности следующих выдач. [Планировщик](ux-ui/acceptance/acme259-renewal.json).
+
+После продления native logical name ровно1, unfinished _new_0; прежний leaf сохранён в одном _old_<12hex> с теми же ID/SHA-256/private-key. Новый ID и SHA-256 отличаются. Trusted TLS обслуживает новый leaf, canonical validFrom/validUntil совпадают с X509; обычный HTTPS REST200 после продления. [Ротация](ux-ui/acceptance/acme259-native-rotation.json), [новый TLS](ux-ui/acceptance/acme259-tls-after.json), [сравнение](ux-ui/acceptance/acme259-tls-comparison.json). Это успешная конкретная последовательная ротация двух SSL служб; zero-downtime, другие потребители старого ключа и несколько issuers не заявляются.
+
+Очистка: SSL baseline → только собственные поколения/CA/files → два own terminal jobs → исходные ACME/renew settings целиком. Приложение удалило TXT; собственная A удалена по exact ID/name/type/content, оба DNS имени0. После scheduler refresh повторно восстановлены исходные SQL timestamps/meta. Native certificates/files/SSL, normalized export и приватные SQL строки совпали; при сравнении files исключён last-modified, export — комментарии/пустые строки. Private baseline/key fixtures удалены на Debian и локально. Оба CHR доступны, пароли не менялись. [Откат](ux-ui/acceptance/acme259-cleanup.json), [DNS](ux-ui/acceptance/acme259-cloudflare.json).
+
+В ручном helper SQL count оказался number0, не string0: первая проверка restore остановилась до device writes, тип ожидания исправлен. Диагностический SELECT с несуществующим created_at отклонён без записей. Эти ошибки приёмочного кода не скрыты и не считаются дефектами продукта. Для неизменённого production кода build/profile не повторялись:258 уже проверен9 scripts/build/lint, общая transport regression257 —25 profiles. CA revocation не выполнен; удаление native сертификата не означает отзыв CA. Следующий260 — актуальный остаток и профильный UX/a11y/performance контроль.
+
## 12.5.258 — уникальное новое поколение и сохранение старого сертификата (2026-10-15)
После256/257 issuer проверяет duplicate logical name ещё до CA order. Leaf/key получают случайное уникальное имя _new_<12hex>, signed X509 fingerprint вычисляется до native upload. rotateCertificateGeneration требует подтверждённые разные native IDs и свободное archive name; сначала проверяет новый leaf/private-key и назначения обоих SSL сервисов на него. Только после этого прежний logical объект переносится в _old_<12hex>, новый получает прежнее logical name и повторно проверяются fingerprint/private-key/services. Старый объект/ключ не удаляется, данные jobs/requestId остаются совместимыми.
diff --git a/docs/ux-ui-test-server.md b/docs/ux-ui-test-server.md
index 1c60c060..24936032 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-15: 258 — реализована unique generation rotation с проверкой нового leaf/SSL до архивации старого, сохранением прежнего ключа и финальным logical name. Profile9/build/lint passed, image ux-certificates258 source530/dist1084 prepared, ещё не активирован; runtime backend257/frontend251. Следующий259 — согласованный real first issue + scheduler renewal, trusted TLS, unique logical name/old archive и полный откат; разрешение сохраняется. Этап12.5 открыт.
+Актуальное продолжение 2026-10-15: 259 — реальный first issue и scheduler renewal приняты: trusted TLS сменил SHA-256, один logical leaf, старые native ID/fingerprint/private-key сохранены в архиве. Native/export/SSL/SQL/DNS восстановлены, private fixtures удалены. Runtime backend258/frontend251 healthy. Следующий260 — актуализировать остаток и выполнить профильную приёмку UX/доступности/производительности; этап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-peak190 и mmapp-test/frontend:ux-warning183; запущены |
+| Образы приложения | mmapp-test/backend:ux-certificates258 и mmapp-test/frontend:ux-certificates251; backend healthy, проверено2026-10-15 в259 |
Compose SHA256:3052bd6ab5d9865f97605cebfb5ff27a4410cd3357b81153a65a87fb7c92582f. OptionalBACKEND_IMAGE_TAG позволяетобновлятьbackendотдельно. Локальный и удалённый файлы совпали. Шаблоны: [Compose](../deploy/docker-compose.test.yml), [env без секретов](../deploy/env.test.example).
@@ -34,6 +34,20 @@ OSPF84: real GRE Full adjacency/private routes/Ping3/3 и4 live PC/320px URL/bro
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 без новой сборки. [Отчёт](ux-ui/acceptance/ospf-bfd-loss-2026-10-09.json).
+## 12.5.259 — реальная ротация сертификата и подтверждённый откат (2026-10-15)
+
+По сохранённому разрешению254 выполнен тот же exact mmt253-8e62a941.pngs.top на104.165.244.7. Перед началом снят свежий приватный native/export/SSL/files/SQL baseline; own certificate/files/jobs/DNS0, Cloudflare token/zone/account проверены. Renewal временно выключен. Подготовленный backend258 активирован; frontend251/Portal/DB сохранены, backend healthy. [Развёртывание](ux-ui/acceptance/acme259-deployment.json).
+
+Настоящий Portal/UI без mocks: один manual issue POST, terminal done, JS errors0. Native logical leaf единственный, private-key=true, обе SSL службы enabled с logical name. Независимый trusted TLS/SNI/hostname совпал с native SHA-256. [UI](ux-ui/acceptance/acme259-live-ui.json), [первый TLS](ux-ui/acceptance/acme259-tls-before.json).
+
+Один PUT enabled=true запустил штатный certificates_renew; отдельный run-now0. Canonical validity распознан, daysLeft90; revocationStatusunknown не подменяется valid. Единственная цель, scheduler ok/renewed1/errors0, затем renewal сразу disabled. Реальный цикл31.488s — не гарантия длительности следующих выдач. [Планировщик](ux-ui/acceptance/acme259-renewal.json).
+
+После продления native logical name ровно1, unfinished _new_0; прежний leaf сохранён в одном _old_<12hex> с теми же ID/SHA-256/private-key. Новый ID и SHA-256 отличаются. Trusted TLS обслуживает новый leaf, canonical validFrom/validUntil совпадают с X509; обычный HTTPS REST200 после продления. [Ротация](ux-ui/acceptance/acme259-native-rotation.json), [новый TLS](ux-ui/acceptance/acme259-tls-after.json), [сравнение](ux-ui/acceptance/acme259-tls-comparison.json). Это успешная конкретная последовательная ротация двух SSL служб; zero-downtime, другие потребители старого ключа и несколько issuers не заявляются.
+
+Очистка: SSL baseline → только собственные поколения/CA/files → два own terminal jobs → исходные ACME/renew settings целиком. Приложение удалило TXT; собственная A удалена по exact ID/name/type/content, оба DNS имени0. После scheduler refresh повторно восстановлены исходные SQL timestamps/meta. Native certificates/files/SSL, normalized export и приватные SQL строки совпали; при сравнении files исключён last-modified, export — комментарии/пустые строки. Private baseline/key fixtures удалены на Debian и локально. Оба CHR доступны, пароли не менялись. [Откат](ux-ui/acceptance/acme259-cleanup.json), [DNS](ux-ui/acceptance/acme259-cloudflare.json).
+
+В ручном helper SQL count оказался number0, не string0: первая проверка restore остановилась до device writes, тип ожидания исправлен. Диагностический SELECT с несуществующим created_at отклонён без записей. Эти ошибки приёмочного кода не скрыты и не считаются дефектами продукта. Для неизменённого production кода build/profile не повторялись:258 уже проверен9 scripts/build/lint, общая transport regression257 —25 profiles. CA revocation не выполнен; удаление native сертификата не означает отзыв CA. Следующий260 — актуальный остаток и профильный UX/a11y/performance контроль.
+
## 12.5.258 — уникальное новое поколение и сохранение старого сертификата (2026-10-15)
После256/257 issuer проверяет duplicate logical name ещё до CA order. Leaf/key получают случайное уникальное имя _new_<12hex>, signed X509 fingerprint вычисляется до native upload. rotateCertificateGeneration требует подтверждённые разные native IDs и свободное archive name; сначала проверяет новый leaf/private-key и назначения обоих SSL сервисов на него. Только после этого прежний logical объект переносится в _old_<12hex>, новый получает прежнее logical name и повторно проверяются fingerprint/private-key/services. Старый объект/ключ не удаляется, данные jobs/requestId остаются совместимыми.
diff --git a/docs/ux-ui/acceptance/acme259-cleanup.json b/docs/ux-ui/acceptance/acme259-cleanup.json
new file mode 100644
index 00000000..539c7981
--- /dev/null
+++ b/docs/ux-ui/acceptance/acme259-cleanup.json
@@ -0,0 +1,27 @@
+{
+ "date": "2026-10-15",
+ "block": "12.5.259",
+ "nativeCertificatesRestored": true,
+ "nativeFilesRestored": true,
+ "sslServicesRestored": true,
+ "normalizedExportRestored": true,
+ "privateSqlSettingsRestored": true,
+ "ownJobs": 0,
+ "exportSha256": "3d7d864c2e8d9e7c2bba3ef59aa64b7d05e2a660d4d307172c36c555184b6066",
+ "passwordsUnchanged": true,
+ "jobs": [
+ {
+ "id": "60f3d7b3-9679-4c4c-9de6-800b8ffd726b",
+ "status": "done",
+ "source": "manual"
+ },
+ {
+ "id": "a344479f-6144-4bb5-b678-a37b27d91860",
+ "status": "done",
+ "source": "scheduler"
+ }
+ ],
+ "cloudflareExactNamesEmpty": true,
+ "remotePrivateFilesRemoved": true,
+ "localPrivateFixtureRemoved": true
+}
diff --git a/docs/ux-ui/acceptance/acme259-cloudflare.json b/docs/ux-ui/acceptance/acme259-cloudflare.json
new file mode 100644
index 00000000..d8273573
--- /dev/null
+++ b/docs/ux-ui/acceptance/acme259-cloudflare.json
@@ -0,0 +1,33 @@
+{
+ "date": "2026-10-15",
+ "block": "12.5.259",
+ "domain": "pngs.top",
+ "checks": [
+ {
+ "endpoint": "/user/tokens/verify",
+ "status": 200,
+ "success": true,
+ "errors": []
+ },
+ {
+ "endpoint": "/zones?name=pngs.top",
+ "status": 200,
+ "success": true,
+ "errors": []
+ }
+ ],
+ "tokenActive": true,
+ "zoneActive": true,
+ "accountMatched": true,
+ "nameservers": [
+ "cheryl.ns.cloudflare.com",
+ "doug.ns.cloudflare.com"
+ ],
+ "originalFqdnRecords": 0,
+ "originalChallengeRecords": 0,
+ "fqdn": "mmt253-8e62a941.pngs.top",
+ "applicationTxtCleanupConfirmed": true,
+ "ownARecordDeleted": true,
+ "finalFqdnRecords": 0,
+ "finalChallengeRecords": 0
+}
diff --git a/docs/ux-ui/acceptance/acme259-deployment.json b/docs/ux-ui/acceptance/acme259-deployment.json
new file mode 100644
index 00000000..c1612721
--- /dev/null
+++ b/docs/ux-ui/acceptance/acme259-deployment.json
@@ -0,0 +1,16 @@
+{
+ "date": "2026-10-15",
+ "block": "12.5.259",
+ "backendImage": "mmapp-test/backend:ux-certificates258",
+ "imageId": "sha256:984684709e619972bae8657208e3150d12f1c4f2b5642fecf5286a5d87e9fe71",
+ "health": "healthy",
+ "frontendImage": "mmapp-test/frontend:ux-certificates251",
+ "preparedImageEvidence": "certificates258-preparation.json",
+ "newProductionCode": false,
+ "firstIssueAndRenewalAccepted": true,
+ "exactFqdn": "mmt253-8e62a941.pngs.top",
+ "target": "104.165.244.7",
+ "control": "194.226.121.150",
+ "controlReachableAfterCleanup": true,
+ "privateCleanupConfirmed": true
+}
diff --git a/docs/ux-ui/acceptance/acme259-live-ui.json b/docs/ux-ui/acceptance/acme259-live-ui.json
new file mode 100644
index 00000000..a1391d04
--- /dev/null
+++ b/docs/ux-ui/acceptance/acme259-live-ui.json
@@ -0,0 +1,35 @@
+{
+ "date": "2026-10-15",
+ "block": "12.5.259",
+ "fqdn": "mmt253-8e62a941.pngs.top",
+ "certName": "mmt253-8e62a941",
+ "serverId": "2",
+ "realPortalLogin": true,
+ "noMocks": true,
+ "issuePosts": 1,
+ "pageErrors": [],
+ "settings": {
+ "testStatus": 200,
+ "testOk": true,
+ "saveStatus": 200,
+ "tokenConfigured": true,
+ "directoryUrl": "https://acme-v02.api.letsencrypt.org/directory"
+ },
+ "jobId": "60f3d7b3-9679-4c4c-9de6-800b8ffd726b",
+ "accepted": true,
+ "job": {
+ "id": "60f3d7b3-9679-4c4c-9de6-800b8ffd726b",
+ "status": "done",
+ "step": "done"
+ },
+ "uiTerminalConfirmed": true,
+ "postCleanup": {
+ "tokenConfigured": false,
+ "ownJobStatus": 404,
+ "reachableServerIds": [
+ "1",
+ "2"
+ ],
+ "ownCertificateAbsent": true
+ }
+}
diff --git a/docs/ux-ui/acceptance/acme259-native-rotation.json b/docs/ux-ui/acceptance/acme259-native-rotation.json
new file mode 100644
index 00000000..1ed4be64
--- /dev/null
+++ b/docs/ux-ui/acceptance/acme259-native-rotation.json
@@ -0,0 +1,73 @@
+{
+ "date": "2026-10-15",
+ "block": "12.5.259",
+ "before": {
+ "fqdn": "mmt253-8e62a941.pngs.top",
+ "certName": "mmt253-8e62a941",
+ "nativePrivateKey": true,
+ "nativeFingerprint256": "4d795d55910379177cb72a10dbaa4715ef1a4eeeca9dffb0db7a15e62593bd0a",
+ "logicalId": "*1",
+ "logicalNames": 1,
+ "archives": [],
+ "services": [
+ {
+ "name": "www-ssl",
+ "certificate": "mmt253-8e62a941",
+ "disabled": "false"
+ },
+ {
+ "name": "api-ssl",
+ "certificate": "mmt253-8e62a941",
+ "disabled": "false"
+ }
+ ]
+ },
+ "after": {
+ "fqdn": "mmt253-8e62a941.pngs.top",
+ "certName": "mmt253-8e62a941",
+ "nativePrivateKey": true,
+ "nativeFingerprint256": "ecd158f17450ca1f8442374cb9d23e9de6c28fce6ff001ec7a6825e577657324",
+ "logicalId": "*4",
+ "logicalNames": 1,
+ "archives": [
+ {
+ "id": "*1",
+ "name": "mmt253-8e62a941_old_db6003fc0c3d",
+ "fingerprint": "4d795d55910379177cb72a10dbaa4715ef1a4eeeca9dffb0db7a15e62593bd0a",
+ "privateKey": "true"
+ }
+ ],
+ "services": [
+ {
+ "name": "www-ssl",
+ "certificate": "mmt253-8e62a941",
+ "disabled": "false"
+ },
+ {
+ "name": "api-ssl",
+ "certificate": "mmt253-8e62a941",
+ "disabled": "false"
+ }
+ ]
+ },
+ "canonicalDatesMatchX509": true,
+ "canonicalDates": {
+ "validFrom": "2026-10-15T05:41:17.000Z",
+ "validUntil": "2027-01-13T05:41:16.000Z",
+ "daysLeft": 90,
+ "status": "unknown"
+ },
+ "trustedHttpsRestAfterRenewal": 200,
+ "realPortalViews": [
+ {
+ "width": 1440,
+ "overflow": false
+ },
+ {
+ "width": 390,
+ "overflow": false
+ }
+ ],
+ "pageErrors": [],
+ "nonAuthApiWrites": 0
+}
diff --git a/docs/ux-ui/acceptance/acme259-renewal.json b/docs/ux-ui/acceptance/acme259-renewal.json
new file mode 100644
index 00000000..407d051e
--- /dev/null
+++ b/docs/ux-ui/acceptance/acme259-renewal.json
@@ -0,0 +1,59 @@
+{
+ "date": "2026-10-15",
+ "block": "12.5.259",
+ "fqdn": "mmt253-8e62a941.pngs.top",
+ "enableRequests": 1,
+ "runNowRequests": 0,
+ "eligibility": {
+ "validFrom": "2026-10-15T05:39:27.000Z",
+ "validUntil": "2027-01-13T05:39:26.000Z",
+ "daysLeft": 90,
+ "revocationStatus": "unknown"
+ },
+ "run": {
+ "id": "sch-1792046395326-8ysbwrkl",
+ "jobKey": "certificates_renew",
+ "startedAt": "2026-10-15 06:39:23.838+00",
+ "finishedAt": "2026-10-15 06:39:55.326+00",
+ "status": "ok",
+ "error": null,
+ "durationMs": 31488,
+ "resultJson": {
+ "v": 1,
+ "job": "certificates_renew",
+ "errors": [],
+ "checked": 1,
+ "renewed": 1,
+ "targets": [
+ {
+ "action": "renewed",
+ "message": "Задача обновления завершена",
+ "certName": "mmt253-8e62a941",
+ "daysLeft": 90,
+ "serverId": "2"
+ }
+ ],
+ "sampledAt": "2026-10-15T06:39:23.838Z",
+ "skippedTargets": 0
+ }
+ },
+ "snapshot": {
+ "v": 1,
+ "job": "certificates_renew",
+ "errors": [],
+ "checked": 1,
+ "renewed": 1,
+ "targets": [
+ {
+ "action": "renewed",
+ "message": "Задача обновления завершена",
+ "certName": "mmt253-8e62a941",
+ "daysLeft": 90,
+ "serverId": "2"
+ }
+ ],
+ "sampledAt": "2026-10-15T06:39:23.838Z",
+ "skippedTargets": 0
+ },
+ "disabledAfterRun": true
+}
diff --git a/docs/ux-ui/acceptance/acme259-tls-after.json b/docs/ux-ui/acceptance/acme259-tls-after.json
new file mode 100644
index 00000000..aac4450f
--- /dev/null
+++ b/docs/ux-ui/acceptance/acme259-tls-after.json
@@ -0,0 +1,15 @@
+{
+ "sampledAt": "2026-10-15T06:40:59.300Z",
+ "fqdn": "mmt253-8e62a941.pngs.top",
+ "certName": "mmt253-8e62a941",
+ "remoteAddress": "104.165.244.7",
+ "authorized": true,
+ "hostnameMatched": true,
+ "protocol": "TLSv1.2",
+ "fingerprint256": "EC:D1:58:F1:74:50:CA:1F:84:42:37:4C:B9:D2:3E:9D:E6:C2:8F:CE:6F:F0:01:EC:7A:68:25:E5:77:65:73:24",
+ "validFrom": "Oct 15 05:41:17 2026 GMT",
+ "validUntil": "Jan 13 05:41:16 2027 GMT",
+ "nativeName": "mmt253-8e62a941",
+ "nativePrivateKey": true,
+ "nativeFingerprint256": "ecd158f17450ca1f8442374cb9d23e9de6c28fce6ff001ec7a6825e577657324"
+}
diff --git a/docs/ux-ui/acceptance/acme259-tls-before.json b/docs/ux-ui/acceptance/acme259-tls-before.json
new file mode 100644
index 00000000..612d046b
--- /dev/null
+++ b/docs/ux-ui/acceptance/acme259-tls-before.json
@@ -0,0 +1,15 @@
+{
+ "sampledAt": "2026-10-15T06:39:13.617Z",
+ "fqdn": "mmt253-8e62a941.pngs.top",
+ "certName": "mmt253-8e62a941",
+ "remoteAddress": "104.165.244.7",
+ "authorized": true,
+ "hostnameMatched": true,
+ "protocol": "TLSv1.2",
+ "fingerprint256": "4D:79:5D:55:91:03:79:17:7C:B7:2A:10:DB:AA:47:15:EF:1A:4E:EE:CA:9D:FF:B0:DB:7A:15:E6:25:93:BD:0A",
+ "validFrom": "Oct 15 05:39:27 2026 GMT",
+ "validUntil": "Jan 13 05:39:26 2027 GMT",
+ "nativeName": "mmt253-8e62a941",
+ "nativePrivateKey": true,
+ "nativeFingerprint256": "4d795d55910379177cb72a10dbaa4715ef1a4eeeca9dffb0db7a15e62593bd0a"
+}
diff --git a/docs/ux-ui/acceptance/acme259-tls-comparison.json b/docs/ux-ui/acceptance/acme259-tls-comparison.json
new file mode 100644
index 00000000..c8f00b57
--- /dev/null
+++ b/docs/ux-ui/acceptance/acme259-tls-comparison.json
@@ -0,0 +1,5 @@
+{
+ "fingerprintChanged": true,
+ "nativeAndTlsMatch": true,
+ "trustedHostnameMatch": true
+}