fix(certificates): продлевать по подтверждённому сроку и проверить реальный импорт

This commit is contained in:
Denozordec committed 2026-10-15 00:05:03 +07:00
1 parent 0e86628d58
commit 9178ff2ccb
19 files changed
+431 -13

No files matched your search

@@ -3,6 +3,7 @@ import { createCertificateRenewCollector } from "./certificate-renew-collector.j
import { getServerRowByIdString } from "./certificates-service.js"
import type { CertificateIssueJobRow } from "../db/schema.js"
import type { RosCertificateRow } from "./certificate-parse.js"
import { readCertificateRowsWithClock } from "./certificates-state.js"
function fixture() {
const settings = { enabled: true, intervalSec: 300, renewBeforeDays: 30, lastCollectedAt: null, lastDurationMs: null, lastError: null, updatedAt: new Date().toISOString() }
@@ -12,14 +13,15 @@ function fixture() {
let job: CertificateIssueJobRow | null = null, outcome: CertificateIssueJobRow["status"] = "done", readFailure = false, active = false
let resultPatch: Partial<CertificateIssueJobRow> = {}, missingResult = false, targetGate: Promise<void> | undefined
let reads = 0, creates = 0, issues = 0
let readResult: unknown
const collector = createCertificateRenewCollector({
getSettings: async () => settings, getTargets: async () => { await targetGate; return [target] }, hasActiveJob: async () => active, getServer: async () => server,
read: async () => { reads++; if (readFailure) throw new Error("RouterOS offline"); return rows },
read: async () => { reads++; if (readFailure) throw new Error("RouterOS offline"); return readResult ?? rows },
createJob: async input => { creates++; job = { ...input, serverId: Number(input.serverId), status: "queued", step: "queued", source: "scheduler", requestedAt: new Date().toISOString(), startedAt: null, finishedAt: null, error: null } },
runJob: async () => { issues++; assert(job); job.status = outcome; job.step = outcome; job.error = outcome === "failed" ? "import refused" : null },
getJob: async () => missingResult || !job ? null : { ...job, ...resultPatch }, touchMeta: async () => {}, event: async () => {},
})
return { collector, settings, target, counts: () => ({ reads, creates, issues }), setServer: (v: typeof server) => { server = v }, setRows: (v: typeof rows) => { rows = v }, setOutcome: (v: typeof outcome) => { outcome = v }, failRead: () => { readFailure = true }, setActive: () => { active = true }, rows: () => rows, patchResult: (v: typeof resultPatch) => { resultPatch = v }, hideResult: () => { missingResult = true }, blockTargets: (v: Promise<void>) => { targetGate = v } }
return { collector, settings, target, counts: () => ({ reads, creates, issues }), setServer: (v: typeof server) => { server = v }, setRows: (v: typeof rows) => { rows = v }, setReadResult: (v: unknown) => { readResult = v }, setOutcome: (v: typeof outcome) => { outcome = v }, failRead: () => { readFailure = true }, setActive: () => { active = true }, rows: () => rows, patchResult: (v: typeof resultPatch) => { resultPatch = v }, hideResult: () => { missingResult = true }, blockTargets: (v: Promise<void>) => { targetGate = v } }
}
for (const outcome of ["done", "failed", "running", "queued"] as const) {
@@ -60,3 +62,27 @@ for (const patch of [{ serverId: 2 }, { certName: "another" }, { source: "manual
assert.equal((await f.collector.run()).skipped, true); release(); assert.equal((await first).renewed, 1); assert.equal(f.counts().issues, 1)
}
console.log("Renewal: only matching done counts as renewed; failed/pending/disabled/unknown/ambiguous/read error never dispatch or claim success; invalid IDs do not query DB")
for (const offsets of [["+02:00","+02:00"],["+02:00","+01:00"],[null,"+02:00"]]) {
const f=fixture(), native=f.rows().map(row=>({...row,
"invalid-before":new Date(Date.now()-86400000+7200000).toISOString().slice(0,19).replace("T"," "),
"invalid-after":new Date(Date.now()+172800000+7200000).toISOString().slice(0,19).replace("T"," ")}))
let i=0
f.setReadResult(await readCertificateRowsWithClock(async()=>native,async()=>({"gmt-offset":offsets[i++]})))
const result=await f.collector.run(), known=offsets[0]!==null&&offsets[0]===offsets[1]
assert.equal(result.renewed,known?1:0);assert.equal(f.counts().issues,known?1:0);assert.equal(f.counts().creates,known?1:0)
assert.equal(result.targets?.[0].daysLeft,known?2:null)
}
console.log("Native clock → canonical state → renewal: stable offset issues once; missing/changed offset never creates a job")
{
const f=fixture();f.setRows(f.rows().map(row=>({...row,flags:undefined})))
assert.equal((await f.collector.run()).renewed,1);assert.equal(f.counts().issues,1)
}
for(const kind of ["missing-start","future-start","reversed-window"]) {
const f=fixture();f.setRows(f.rows().map(row=>({...row,flags:undefined,
"invalid-before":kind==="missing-start"?undefined:new Date(Date.now()+86400000).toISOString(),
"invalid-after":kind==="reversed-window"?new Date(Date.now()-86400000).toISOString():row["invalid-after"]})))
assert.equal((await f.collector.run()).renewed,0);assert.equal(f.counts().issues,0)
}
console.log("Missing REST revocation flags do not prevent date-based renewal; unknown/future/reversed validity dates remain guarded")
@@ -127,7 +127,9 @@ export function createCertificateRenewCollector(overrides: Partial<typeof defaul
}
item.daysLeft = hit.daysLeft
if (hit.daysLeft === null || hit.status === "unknown") {
// REST may omit revocation flags even for an installed signed leaf.
// Renewal depends on confirmed validity dates, not a claim about revocation.
if (hit.daysLeft === null || !hit.validFrom || !hit.validUntil || Date.parse(hit.validFrom) > Date.now() || Date.parse(hit.validFrom) > Date.parse(hit.validUntil)) {
item.action = "skipped"
item.message = "Срок или состояние сертификата не подтверждены. Обновление не выполнялось."
snapshot.skippedTargets += 1
+19 -1
View File
@@ -1,6 +1,6 @@
# UX/UI: протокол внешней приёмки 12.5
Актуальное продолжение 2026-10-14: 255 — canonical native даты учитывают явно наблюдаемый стабильный gmt-offset, сохраняя raw и unknown при отсутствии/сбое/смене clock. Каталог и renewal используют общий reader; профиль8 scripts/build/lint прошёл. Runtime backend ux-certificates255/frontend ux-certificates251. Следующий256 — повторная реальная issuance + scheduler renewal/fingerprint по уже сохранённому разрешению254, свежий baseline и полный откат; реальный renewal пока не принят. Этап12.5 открыт.
Актуальное продолжение 2026-10-15: 256 — collector renewal использует подтверждённые dates без выдуманного revocation status; профиль/build/lint прошли, backend ux-certificates256/source528/dist1080 healthy. Реальное scheduler renewal выполнилось, served TLS SHA-256 сменился и совпал с новым native leaf, но импорт создал2 одинаковых имени: общая приёмка не завершена. Все own native/DNS/jobs/settings очищены/восстановлены; оба CHR доступны. Следующий257 — запрет ложного success при неоднозначном импорте и стратегия уникальной замены; отдельно лимит REST logins6. Этап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,24 @@ 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.256 — реальный scheduler renewal, дубликаты native имён и полный откат (2026-10-15)
Начат2026-10-14, завершён2026-10-15 по Новосибирску. Пятичасовой лимит сбросился, недельный остался ограниченным. По действующему разрешению254 снят новый native/SQL baseline, own jobs/certificates/DNS0, token/zone/account проверены. Первый UI issue exact mmt253-8e62a941.pngs.top/manual →done, trusted TLS/private-key/native SHA-256 подтверждены. [UI](ux-ui/acceptance/acme256-live-ui.json), [before](ux-ui/acceptance/acme256-tls-before.json).
Native date reader255 теперь правильно даёт validFrom/validUntil в UTC и daysLeft90, совпадающие с X509. Но statusunknown: REST7.24.5 не присылает flags/revoked/expired. Первый enable-triggered run был skipped/renewed0, без нового ACME order; comparator expectation renewed1 не прошёл и сохранён отдельно [skip](ux-ui/acceptance/acme256-renewal-skipped.json). Каталог не должен выдумывать revocation state. Для renewal правило уточнено: достаточно подтверждённого срока и начавшегося непротиворечивого validity window; unknown/missing/changed clock, missing start, future start и reversed window по-прежнему не создают job. Это соответствует прежнему разрешённому renewal даже для explicit revoked/expired, не объявляет сертификат valid.
Collector native-clock→canonical-state→issue тесты: stable offset создаёт одну задачу, changed/missing не создаёт; отсутствующие REST revocation flags с известными dates позволяют renewal, неизвестные/future/reversed dates блокируют. Все8 profile scripts, contracts/backend build, scoped lint passed. Production backend ux-certificates256/source528/compiled1080 совпал, healthy, frontend251/DB/Portal сохранены. Изменённый scope не требовал повтора полной регрессии249.
После исправления один enable-triggered scheduler run (interval86400/threshold90), без run-now: scheduler issue →done, receipt ok/renewed1/errors0, затем enabledfalse до следующего интервала. Реально served TLS сменился с342d36bc… на70b7b9f1… и совпал с новым private-key native leaf; доверие/SNI не отключались. [After](ux-ui/acceptance/acme256-tls-after.json), [jobs](ux-ui/acceptance/acme256-jobs.json), [run](ux-ui/acceptance/acme256-renewal.json).
Приёмка renewal всё равно открыта: /certificate содержит2 leaf с одинаковым logical name mmt253-8e62a941, разными .id/SHA-256 и private-key=true. [Duplicate leaves](ux-ui/acceptance/acme256-duplicate-leaves.json). Next collector отвергнет неоднозначность; import ACK + done не доказывают устойчивую замену. Fresh TLS действительно served new leaf, поэтому не заявляем, что TLS остался старым. До fresh sample ошибочно скопированный вручную fingerprint не прошёл SHA-256 validation; затем использован точный файл native report через SCP. Предусловие statusvalid оказалось неверным для REST flags; первый scheduler run безопасно skipped, после уточнения policy выполнен один реальный order. Не суммируем skip как успешное renewal.
Cleanup сначала столкнулся с REST401/500; точный ответ resource500: too many concurrent logins (6). Временно остановлен только backend, затем восстановлены configured www-ssl/api-ssl, удалены оба own leaf/chain/PEM. Certificates/file stable metadata/configured services/normalized export совпали с fresh baseline; исключены dynamic connections и directory mtime. [Native](ux-ui/acceptance/acme256-native.json). Backend снова запущен и healthy, Portal послеcleanup оба CHR читает безошибочно; пароли не менялись. REST concurrency остаётся отдельным воспроизведённым ограничением.
TXT приложение удалило; own A удалена по exact name/type/content/ID, DNS0 обоихимён [DNS](ux-ui/acceptance/acme256-cloudflare.json). ACME/renew settings восстановлены целиком, scheduler refresh применён, его empty-run metadata затем восстановлена exact SQL compare. Own issue jobs удалены, private token/baseline/helper/SQL файлы удалены с Debian и локальный secret fixture удалён. Historical events/scheduler receipts/CA records сохранены; CA revocation не заявляется.
Следующий257 — post-import подтверждение unique logical name/expected X509 fingerprint/private key перед применением/успехом и безопасная стратегия уникальной замены без потери старого working leaf. Дополнительно проработать per-device REST concurrency/login cap. Эти дефекты не маскируются сообщением successful acceptance; новое разрешение на тот же согласованный сценарий не запрашивается без изменения его риска/объёма.
## 12.5.255 — native даты с подтверждённым offset для каталога и renewal (2026-10-14)
После измерения254 добавлен общий readCertificateRowsWithClock: читает gmt-offset перед каталогом, для native timezone-less дат повторно читает clock после; принимает только одинаковые валидные offsets. Native YYYY-MM-DD HH:mm:ss преобразуется в offset-qualified datetime с проверкой календаря, затем UTC; explicit ISO сохраняет свой offset. Не предполагается UTC/пояс backend/будущий DST. rawValidFrom/rawValidUntil остаются исходными. Отсутствующий/некорректный/сменившийся/недоступный clock сохраняет unknown/null и не обходит renewal guard252; ошибка самого каталога сохраняет error. Legacy старые форматы без надёжного контекста не угадываются.
+19 -1
View File
@@ -1,9 +1,27 @@
# План реализации UX/UI по пятичасовым окнам
Актуальное продолжение 2026-10-14: 255 — canonical native даты учитывают явно наблюдаемый стабильный gmt-offset, сохраняя raw и unknown при отсутствии/сбое/смене clock. Каталог и renewal используют общий reader; профиль8 scripts/build/lint прошёл. Runtime backend ux-certificates255/frontend ux-certificates251. Следующий256 — повторная реальная issuance + scheduler renewal/fingerprint по уже сохранённому разрешению254, свежий baseline и полный откат; реальный renewal пока не принят. Этап12.5 открыт.
Актуальное продолжение 2026-10-15: 256 — collector renewal использует подтверждённые dates без выдуманного revocation status; профиль/build/lint прошли, backend ux-certificates256/source528/dist1080 healthy. Реальное scheduler renewal выполнилось, served TLS SHA-256 сменился и совпал с новым native leaf, но импорт создал2 одинаковых имени: общая приёмка не завершена. Все own native/DNS/jobs/settings очищены/восстановлены; оба CHR доступны. Следующий257 — запрет ложного success при неоднозначном импорте и стратегия уникальной замены; отдельно лимит REST logins6. Этап12.5 открыт.
Общий план проекта MikrotikManager. Основан на согласованном плане из задачи; точка продолжения обновлена 2026-10-14. Источник фактического прогресса, проверок и ограничений — [журнал реализации](ux-ui-progress.md). Этот документ задаёт объём и критерии завершения, журнал фиксирует результат.
## 12.5.256 — реальный scheduler renewal, дубликаты native имён и полный откат (2026-10-15)
Начат2026-10-14, завершён2026-10-15 по Новосибирску. Пятичасовой лимит сбросился, недельный остался ограниченным. По действующему разрешению254 снят новый native/SQL baseline, own jobs/certificates/DNS0, token/zone/account проверены. Первый UI issue exact mmt253-8e62a941.pngs.top/manual →done, trusted TLS/private-key/native SHA-256 подтверждены. [UI](ux-ui/acceptance/acme256-live-ui.json), [before](ux-ui/acceptance/acme256-tls-before.json).
Native date reader255 теперь правильно даёт validFrom/validUntil в UTC и daysLeft90, совпадающие с X509. Но statusunknown: REST7.24.5 не присылает flags/revoked/expired. Первый enable-triggered run был skipped/renewed0, без нового ACME order; comparator expectation renewed1 не прошёл и сохранён отдельно [skip](ux-ui/acceptance/acme256-renewal-skipped.json). Каталог не должен выдумывать revocation state. Для renewal правило уточнено: достаточно подтверждённого срока и начавшегося непротиворечивого validity window; unknown/missing/changed clock, missing start, future start и reversed window по-прежнему не создают job. Это соответствует прежнему разрешённому renewal даже для explicit revoked/expired, не объявляет сертификат valid.
Collector native-clock→canonical-state→issue тесты: stable offset создаёт одну задачу, changed/missing не создаёт; отсутствующие REST revocation flags с известными dates позволяют renewal, неизвестные/future/reversed dates блокируют. Все8 profile scripts, contracts/backend build, scoped lint passed. Production backend ux-certificates256/source528/compiled1080 совпал, healthy, frontend251/DB/Portal сохранены. Изменённый scope не требовал повтора полной регрессии249.
После исправления один enable-triggered scheduler run (interval86400/threshold90), без run-now: scheduler issue →done, receipt ok/renewed1/errors0, затем enabledfalse до следующего интервала. Реально served TLS сменился с342d36bc… на70b7b9f1… и совпал с новым private-key native leaf; доверие/SNI не отключались. [After](ux-ui/acceptance/acme256-tls-after.json), [jobs](ux-ui/acceptance/acme256-jobs.json), [run](ux-ui/acceptance/acme256-renewal.json).
Приёмка renewal всё равно открыта: /certificate содержит2 leaf с одинаковым logical name mmt253-8e62a941, разными .id/SHA-256 и private-key=true. [Duplicate leaves](ux-ui/acceptance/acme256-duplicate-leaves.json). Next collector отвергнет неоднозначность; import ACK + done не доказывают устойчивую замену. Fresh TLS действительно served new leaf, поэтому не заявляем, что TLS остался старым. До fresh sample ошибочно скопированный вручную fingerprint не прошёл SHA-256 validation; затем использован точный файл native report через SCP. Предусловие statusvalid оказалось неверным для REST flags; первый scheduler run безопасно skipped, после уточнения policy выполнен один реальный order. Не суммируем skip как успешное renewal.
Cleanup сначала столкнулся с REST401/500; точный ответ resource500: too many concurrent logins (6). Временно остановлен только backend, затем восстановлены configured www-ssl/api-ssl, удалены оба own leaf/chain/PEM. Certificates/file stable metadata/configured services/normalized export совпали с fresh baseline; исключены dynamic connections и directory mtime. [Native](ux-ui/acceptance/acme256-native.json). Backend снова запущен и healthy, Portal послеcleanup оба CHR читает безошибочно; пароли не менялись. REST concurrency остаётся отдельным воспроизведённым ограничением.
TXT приложение удалило; own A удалена по exact name/type/content/ID, DNS0 обоихимён [DNS](ux-ui/acceptance/acme256-cloudflare.json). ACME/renew settings восстановлены целиком, scheduler refresh применён, его empty-run metadata затем восстановлена exact SQL compare. Own issue jobs удалены, private token/baseline/helper/SQL файлы удалены с Debian и локальный secret fixture удалён. Historical events/scheduler receipts/CA records сохранены; CA revocation не заявляется.
Следующий257 — post-import подтверждение unique logical name/expected X509 fingerprint/private key перед применением/успехом и безопасная стратегия уникальной замены без потери старого working leaf. Дополнительно проработать per-device REST concurrency/login cap. Эти дефекты не маскируются сообщением successful acceptance; новое разрешение на тот же согласованный сценарий не запрашивается без изменения его риска/объёма.
## 12.5.255 — native даты с подтверждённым offset для каталога и renewal (2026-10-14)
После измерения254 добавлен общий readCertificateRowsWithClock: читает gmt-offset перед каталогом, для native timezone-less дат повторно читает clock после; принимает только одинаковые валидные offsets. Native YYYY-MM-DD HH:mm:ss преобразуется в offset-qualified datetime с проверкой календаря, затем UTC; explicit ISO сохраняет свой offset. Не предполагается UTC/пояс backend/будущий DST. rawValidFrom/rawValidUntil остаются исходными. Отсутствующий/некорректный/сменившийся/недоступный clock сохраняет unknown/null и не обходит renewal guard252; ошибка самого каталога сохраняет error. Legacy старые форматы без надёжного контекста не угадываются.
+20 -2
View File
@@ -1,6 +1,6 @@
# UX/UI: журнал реализации
Актуальное продолжение 2026-10-14: 255 — canonical native даты учитывают явно наблюдаемый стабильный gmt-offset, сохраняя raw и unknown при отсутствии/сбое/смене clock. Каталог и renewal используют общий reader; профиль8 scripts/build/lint прошёл. Runtime backend ux-certificates255/frontend ux-certificates251. Следующий256 — повторная реальная issuance + scheduler renewal/fingerprint по уже сохранённому разрешению254, свежий baseline и полный откат; реальный renewal пока не принят. Этап12.5 открыт.
Актуальное продолжение 2026-10-15: 256 — collector renewal использует подтверждённые dates без выдуманного revocation status; профиль/build/lint прошли, backend ux-certificates256/source528/dist1080 healthy. Реальное scheduler renewal выполнилось, served TLS SHA-256 сменился и совпал с новым native leaf, но импорт создал2 одинаковых имени: общая приёмка не завершена. Все own native/DNS/jobs/settings очищены/восстановлены; оба CHR доступны. Следующий257 — запрет ложного success при неоднозначном импорте и стратегия уникальной замены; отдельно лимит REST logins6. Этап12.5 открыт.
Общий план: [UX/UI по этапам и пятичасовым окнам](ux-ui-plan.md). План задаёт объём, этот журнал фиксирует выполненные блоки и ограничения. Записи расположены от новых к старым; подробная история этапа12 также сохранена в [ux-ui-stage-12.md](ux-ui-stage-12.md).
@@ -36,7 +36,25 @@
| 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–255 в записанных scopes; исправление timezone255 проверено локально, реальный renewal256 ещё открыт в записанных scopes. Runtime backend ux-certificates255/frontend ux-certificates251. Общая регрессия249 и профиль сертификатов252 прошли; реальный renewal остаётся открытым. |
| 12 | Итоговая доступность, адаптивность, производительность и регрессия | Локальная12.3.83; внешняя12.5 открыта, блоки1–256 в записанных scopes; real renewal/TLS256 выполнен, дубликаты native имён и REST concurrency остаются открыты в записанных scopes. Runtime backend ux-certificates256/frontend ux-certificates251. Общая регрессия249 и профиль сертификатов252 прошли; реальный renewal остаётся открытым. |
## 12.5.256 — реальный scheduler renewal, дубликаты native имён и полный откат (2026-10-15)
Начат2026-10-14, завершён2026-10-15 по Новосибирску. Пятичасовой лимит сбросился, недельный остался ограниченным. По действующему разрешению254 снят новый native/SQL baseline, own jobs/certificates/DNS0, token/zone/account проверены. Первый UI issue exact mmt253-8e62a941.pngs.top/manual →done, trusted TLS/private-key/native SHA-256 подтверждены. [UI](ux-ui/acceptance/acme256-live-ui.json), [before](ux-ui/acceptance/acme256-tls-before.json).
Native date reader255 теперь правильно даёт validFrom/validUntil в UTC и daysLeft90, совпадающие с X509. Но statusunknown: REST7.24.5 не присылает flags/revoked/expired. Первый enable-triggered run был skipped/renewed0, без нового ACME order; comparator expectation renewed1 не прошёл и сохранён отдельно [skip](ux-ui/acceptance/acme256-renewal-skipped.json). Каталог не должен выдумывать revocation state. Для renewal правило уточнено: достаточно подтверждённого срока и начавшегося непротиворечивого validity window; unknown/missing/changed clock, missing start, future start и reversed window по-прежнему не создают job. Это соответствует прежнему разрешённому renewal даже для explicit revoked/expired, не объявляет сертификат valid.
Collector native-clock→canonical-state→issue тесты: stable offset создаёт одну задачу, changed/missing не создаёт; отсутствующие REST revocation flags с известными dates позволяют renewal, неизвестные/future/reversed dates блокируют. Все8 profile scripts, contracts/backend build, scoped lint passed. Production backend ux-certificates256/source528/compiled1080 совпал, healthy, frontend251/DB/Portal сохранены. Изменённый scope не требовал повтора полной регрессии249.
После исправления один enable-triggered scheduler run (interval86400/threshold90), без run-now: scheduler issue →done, receipt ok/renewed1/errors0, затем enabledfalse до следующего интервала. Реально served TLS сменился с342d36bc… на70b7b9f1… и совпал с новым private-key native leaf; доверие/SNI не отключались. [After](ux-ui/acceptance/acme256-tls-after.json), [jobs](ux-ui/acceptance/acme256-jobs.json), [run](ux-ui/acceptance/acme256-renewal.json).
Приёмка renewal всё равно открыта: /certificate содержит2 leaf с одинаковым logical name mmt253-8e62a941, разными .id/SHA-256 и private-key=true. [Duplicate leaves](ux-ui/acceptance/acme256-duplicate-leaves.json). Next collector отвергнет неоднозначность; import ACK + done не доказывают устойчивую замену. Fresh TLS действительно served new leaf, поэтому не заявляем, что TLS остался старым. До fresh sample ошибочно скопированный вручную fingerprint не прошёл SHA-256 validation; затем использован точный файл native report через SCP. Предусловие statusvalid оказалось неверным для REST flags; первый scheduler run безопасно skipped, после уточнения policy выполнен один реальный order. Не суммируем skip как успешное renewal.
Cleanup сначала столкнулся с REST401/500; точный ответ resource500: too many concurrent logins (6). Временно остановлен только backend, затем восстановлены configured www-ssl/api-ssl, удалены оба own leaf/chain/PEM. Certificates/file stable metadata/configured services/normalized export совпали с fresh baseline; исключены dynamic connections и directory mtime. [Native](ux-ui/acceptance/acme256-native.json). Backend снова запущен и healthy, Portal послеcleanup оба CHR читает безошибочно; пароли не менялись. REST concurrency остаётся отдельным воспроизведённым ограничением.
TXT приложение удалило; own A удалена по exact name/type/content/ID, DNS0 обоихимён [DNS](ux-ui/acceptance/acme256-cloudflare.json). ACME/renew settings восстановлены целиком, scheduler refresh применён, его empty-run metadata затем восстановлена exact SQL compare. Own issue jobs удалены, private token/baseline/helper/SQL файлы удалены с Debian и локальный secret fixture удалён. Historical events/scheduler receipts/CA records сохранены; CA revocation не заявляется.
Следующий257 — post-import подтверждение unique logical name/expected X509 fingerprint/private key перед применением/успехом и безопасная стратегия уникальной замены без потери старого working leaf. Дополнительно проработать per-device REST concurrency/login cap. Эти дефекты не маскируются сообщением successful acceptance; новое разрешение на тот же согласованный сценарий не запрашивается без изменения его риска/объёма.
## 12.5.255 — native даты с подтверждённым offset для каталога и renewal (2026-10-14)
+22 -4
View File
@@ -1,10 +1,28 @@
# Оставшаяся внешняя приёмка — 2026-10-14
Актуальное продолжение 2026-10-14: 255 — canonical native даты учитывают явно наблюдаемый стабильный gmt-offset, сохраняя raw и unknown при отсутствии/сбое/смене clock. Каталог и renewal используют общий reader; профиль8 scripts/build/lint прошёл. Runtime backend ux-certificates255/frontend ux-certificates251. Следующий256 — повторная реальная issuance + scheduler renewal/fingerprint по уже сохранённому разрешению254, свежий baseline и полный откат; реальный renewal пока не принят. Этап12.5 открыт.
Актуальное продолжение 2026-10-15: 256 — collector renewal использует подтверждённые dates без выдуманного revocation status; профиль/build/lint прошли, backend ux-certificates256/source528/dist1080 healthy. Реальное scheduler renewal выполнилось, served TLS SHA-256 сменился и совпал с новым native leaf, но импорт создал2 одинаковых имени: общая приёмка не завершена. Все own native/DNS/jobs/settings очищены/восстановлены; оба CHR доступны. Следующий257 — запрет ложного success при неоднозначном импорте и стратегия уникальной замены; отдельно лимит REST logins6. Этап12.5 открыт.
Это актуальная матрица после 12.5.255. Исторические записи сохраняют версии и ограничения на момент выполнения; поздние проверки ниже уточняют их. Этап 12.5 открыт. Успех в двух CHR и одном backend не означает приёмку всех конфигураций, интеграций или полной регрессии.
Это актуальная матрица после 12.5.256. Исторические записи сохраняют версии и ограничения на момент выполнения; поздние проверки ниже уточняют их. Этап 12.5 открыт. Успех в двух CHR и одном backend не означает приёмку всех конфигураций, интеграций или полной регрессии.
Стенд: Debian13/Compose, PostgreSQL18.6, два CHR RouterOS7.24.5. Backend `ux-certificates255`, 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-certificates256`, frontend `ux-certificates251`; production lab с195 использует AUTH_REQUIRED=true и Portal1.3.1. Подписанные JWT/RBAC проверялись в изолированных процессах. Все собственные объекты112 удалены, исходные13 коллекций×2 (включая logging/certificates/files/routes) проверены; пароли не менялись.
## 12.5.256 — реальный scheduler renewal, дубликаты native имён и полный откат (2026-10-15)
Начат2026-10-14, завершён2026-10-15 по Новосибирску. Пятичасовой лимит сбросился, недельный остался ограниченным. По действующему разрешению254 снят новый native/SQL baseline, own jobs/certificates/DNS0, token/zone/account проверены. Первый UI issue exact mmt253-8e62a941.pngs.top/manual →done, trusted TLS/private-key/native SHA-256 подтверждены. [UI](ux-ui/acceptance/acme256-live-ui.json), [before](ux-ui/acceptance/acme256-tls-before.json).
Native date reader255 теперь правильно даёт validFrom/validUntil в UTC и daysLeft90, совпадающие с X509. Но statusunknown: REST7.24.5 не присылает flags/revoked/expired. Первый enable-triggered run был skipped/renewed0, без нового ACME order; comparator expectation renewed1 не прошёл и сохранён отдельно [skip](ux-ui/acceptance/acme256-renewal-skipped.json). Каталог не должен выдумывать revocation state. Для renewal правило уточнено: достаточно подтверждённого срока и начавшегося непротиворечивого validity window; unknown/missing/changed clock, missing start, future start и reversed window по-прежнему не создают job. Это соответствует прежнему разрешённому renewal даже для explicit revoked/expired, не объявляет сертификат valid.
Collector native-clock→canonical-state→issue тесты: stable offset создаёт одну задачу, changed/missing не создаёт; отсутствующие REST revocation flags с известными dates позволяют renewal, неизвестные/future/reversed dates блокируют. Все8 profile scripts, contracts/backend build, scoped lint passed. Production backend ux-certificates256/source528/compiled1080 совпал, healthy, frontend251/DB/Portal сохранены. Изменённый scope не требовал повтора полной регрессии249.
После исправления один enable-triggered scheduler run (interval86400/threshold90), без run-now: scheduler issue →done, receipt ok/renewed1/errors0, затем enabledfalse до следующего интервала. Реально served TLS сменился с342d36bc… на70b7b9f1… и совпал с новым private-key native leaf; доверие/SNI не отключались. [After](ux-ui/acceptance/acme256-tls-after.json), [jobs](ux-ui/acceptance/acme256-jobs.json), [run](ux-ui/acceptance/acme256-renewal.json).
Приёмка renewal всё равно открыта: /certificate содержит2 leaf с одинаковым logical name mmt253-8e62a941, разными .id/SHA-256 и private-key=true. [Duplicate leaves](ux-ui/acceptance/acme256-duplicate-leaves.json). Next collector отвергнет неоднозначность; import ACK + done не доказывают устойчивую замену. Fresh TLS действительно served new leaf, поэтому не заявляем, что TLS остался старым. До fresh sample ошибочно скопированный вручную fingerprint не прошёл SHA-256 validation; затем использован точный файл native report через SCP. Предусловие statusvalid оказалось неверным для REST flags; первый scheduler run безопасно skipped, после уточнения policy выполнен один реальный order. Не суммируем skip как успешное renewal.
Cleanup сначала столкнулся с REST401/500; точный ответ resource500: too many concurrent logins (6). Временно остановлен только backend, затем восстановлены configured www-ssl/api-ssl, удалены оба own leaf/chain/PEM. Certificates/file stable metadata/configured services/normalized export совпали с fresh baseline; исключены dynamic connections и directory mtime. [Native](ux-ui/acceptance/acme256-native.json). Backend снова запущен и healthy, Portal послеcleanup оба CHR читает безошибочно; пароли не менялись. REST concurrency остаётся отдельным воспроизведённым ограничением.
TXT приложение удалило; own A удалена по exact name/type/content/ID, DNS0 обоихимён [DNS](ux-ui/acceptance/acme256-cloudflare.json). ACME/renew settings восстановлены целиком, scheduler refresh применён, его empty-run metadata затем восстановлена exact SQL compare. Own issue jobs удалены, private token/baseline/helper/SQL файлы удалены с Debian и локальный secret fixture удалён. Historical events/scheduler receipts/CA records сохранены; CA revocation не заявляется.
Следующий257 — post-import подтверждение unique logical name/expected X509 fingerprint/private key перед применением/успехом и безопасная стратегия уникальной замены без потери старого working leaf. Дополнительно проработать per-device REST concurrency/login cap. Эти дефекты не маскируются сообщением successful acceptance; новое разрешение на тот же согласованный сценарий не запрашивается без изменения его риска/объёма.
## 12.5.255 — native даты с подтверждённым offset для каталога и renewal (2026-10-14)
@@ -292,7 +310,7 @@ Portal offline JWT действует доexp после logout/role change; э
## Следующая последовательность — 2026-10-14
1. **Сертификаты256:** live catalog/renewal timezone fix255 проверен локально; повторить first issuance + scheduler renewal/fingerprint по действующему разрешению254 с новым baseline и полным откатом. Реальная замена leaf ещё не принята.
1. **Сертификаты257:** real scheduler renewal256 сменил TLS, но создаёт duplicate logical names. Исправить post-import verification/unique replacement; отдельно REST max concurrent logins6. Приёмка пока открыта.
2. **Профильный контроль:** для новых изменений выполнять затронутые SQL/API/UI проверки. Общая регрессия192 выполнена; не повторять её без изменений общей основы или нового основания.
3. **Внешние зависимости:** Portal issuer/login/revoke, Telegram bot/chat/разрешённое сообщение, клиентские ОС, независимые WAN/public IPv6 и scale/multi-instance — отдельные группы по таблице выше. Ограничения текущего стенда не превращать в обещание приёмки всех конфигураций.
+19 -1
View File
@@ -1,6 +1,6 @@
# Этап 12: итоговая приёмка UX/UI
Актуальное продолжение 2026-10-14: 255 — canonical native даты учитывают явно наблюдаемый стабильный gmt-offset, сохраняя raw и unknown при отсутствии/сбое/смене clock. Каталог и renewal используют общий reader; профиль8 scripts/build/lint прошёл. Runtime backend ux-certificates255/frontend ux-certificates251. Следующий256 — повторная реальная issuance + scheduler renewal/fingerprint по уже сохранённому разрешению254, свежий baseline и полный откат; реальный renewal пока не принят. Этап12.5 открыт.
Актуальное продолжение 2026-10-15: 256 — collector renewal использует подтверждённые dates без выдуманного revocation status; профиль/build/lint прошли, backend ux-certificates256/source528/dist1080 healthy. Реальное scheduler renewal выполнилось, served TLS SHA-256 сменился и совпал с новым native leaf, но импорт создал2 одинаковых имени: общая приёмка не завершена. Все own native/DNS/jobs/settings очищены/восстановлены; оба CHR доступны. Следующий257 — запрет ложного success при неоднозначном импорте и стратегия уникальной замены; отдельно лимит REST logins6. Этап12.5 открыт.
План: [ux-ui-plan.md](ux-ui-plan.md). Фактические результаты: [ux-ui-progress.md](ux-ui-progress.md). Подготовлен после сводных проверок 11Б; завершение каждого блока требует локального коммита без push.
@@ -4152,6 +4152,24 @@ 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.256 — реальный scheduler renewal, дубликаты native имён и полный откат (2026-10-15)
Начат2026-10-14, завершён2026-10-15 по Новосибирску. Пятичасовой лимит сбросился, недельный остался ограниченным. По действующему разрешению254 снят новый native/SQL baseline, own jobs/certificates/DNS0, token/zone/account проверены. Первый UI issue exact mmt253-8e62a941.pngs.top/manual →done, trusted TLS/private-key/native SHA-256 подтверждены. [UI](ux-ui/acceptance/acme256-live-ui.json), [before](ux-ui/acceptance/acme256-tls-before.json).
Native date reader255 теперь правильно даёт validFrom/validUntil в UTC и daysLeft90, совпадающие с X509. Но statusunknown: REST7.24.5 не присылает flags/revoked/expired. Первый enable-triggered run был skipped/renewed0, без нового ACME order; comparator expectation renewed1 не прошёл и сохранён отдельно [skip](ux-ui/acceptance/acme256-renewal-skipped.json). Каталог не должен выдумывать revocation state. Для renewal правило уточнено: достаточно подтверждённого срока и начавшегося непротиворечивого validity window; unknown/missing/changed clock, missing start, future start и reversed window по-прежнему не создают job. Это соответствует прежнему разрешённому renewal даже для explicit revoked/expired, не объявляет сертификат valid.
Collector native-clock→canonical-state→issue тесты: stable offset создаёт одну задачу, changed/missing не создаёт; отсутствующие REST revocation flags с известными dates позволяют renewal, неизвестные/future/reversed dates блокируют. Все8 profile scripts, contracts/backend build, scoped lint passed. Production backend ux-certificates256/source528/compiled1080 совпал, healthy, frontend251/DB/Portal сохранены. Изменённый scope не требовал повтора полной регрессии249.
После исправления один enable-triggered scheduler run (interval86400/threshold90), без run-now: scheduler issue →done, receipt ok/renewed1/errors0, затем enabledfalse до следующего интервала. Реально served TLS сменился с342d36bc… на70b7b9f1… и совпал с новым private-key native leaf; доверие/SNI не отключались. [After](ux-ui/acceptance/acme256-tls-after.json), [jobs](ux-ui/acceptance/acme256-jobs.json), [run](ux-ui/acceptance/acme256-renewal.json).
Приёмка renewal всё равно открыта: /certificate содержит2 leaf с одинаковым logical name mmt253-8e62a941, разными .id/SHA-256 и private-key=true. [Duplicate leaves](ux-ui/acceptance/acme256-duplicate-leaves.json). Next collector отвергнет неоднозначность; import ACK + done не доказывают устойчивую замену. Fresh TLS действительно served new leaf, поэтому не заявляем, что TLS остался старым. До fresh sample ошибочно скопированный вручную fingerprint не прошёл SHA-256 validation; затем использован точный файл native report через SCP. Предусловие statusvalid оказалось неверным для REST flags; первый scheduler run безопасно skipped, после уточнения policy выполнен один реальный order. Не суммируем skip как успешное renewal.
Cleanup сначала столкнулся с REST401/500; точный ответ resource500: too many concurrent logins (6). Временно остановлен только backend, затем восстановлены configured www-ssl/api-ssl, удалены оба own leaf/chain/PEM. Certificates/file stable metadata/configured services/normalized export совпали с fresh baseline; исключены dynamic connections и directory mtime. [Native](ux-ui/acceptance/acme256-native.json). Backend снова запущен и healthy, Portal послеcleanup оба CHR читает безошибочно; пароли не менялись. REST concurrency остаётся отдельным воспроизведённым ограничением.
TXT приложение удалило; own A удалена по exact name/type/content/ID, DNS0 обоихимён [DNS](ux-ui/acceptance/acme256-cloudflare.json). ACME/renew settings восстановлены целиком, scheduler refresh применён, его empty-run metadata затем восстановлена exact SQL compare. Own issue jobs удалены, private token/baseline/helper/SQL файлы удалены с Debian и локальный secret fixture удалён. Historical events/scheduler receipts/CA records сохранены; CA revocation не заявляется.
Следующий257 — post-import подтверждение unique logical name/expected X509 fingerprint/private key перед применением/успехом и безопасная стратегия уникальной замены без потери старого working leaf. Дополнительно проработать per-device REST concurrency/login cap. Эти дефекты не маскируются сообщением successful acceptance; новое разрешение на тот же согласованный сценарий не запрашивается без изменения его риска/объёма.
## 12.5.255 — native даты с подтверждённым offset для каталога и renewal (2026-10-14)
После измерения254 добавлен общий readCertificateRowsWithClock: читает gmt-offset перед каталогом, для native timezone-less дат повторно читает clock после; принимает только одинаковые валидные offsets. Native YYYY-MM-DD HH:mm:ss преобразуется в offset-qualified datetime с проверкой календаря, затем UTC; explicit ISO сохраняет свой offset. Не предполагается UTC/пояс backend/будущий DST. rawValidFrom/rawValidUntil остаются исходными. Отсутствующий/некорректный/сменившийся/недоступный clock сохраняет unknown/null и не обходит renewal guard252; ошибка самого каталога сохраняет error. Legacy старые форматы без надёжного контекста не угадываются.
+19 -1
View File
@@ -1,6 +1,6 @@
# Тестовый сервер UX/UI — 2026-10-10
Актуальное продолжение 2026-10-14: 255 — canonical native даты учитывают явно наблюдаемый стабильный gmt-offset, сохраняя raw и unknown при отсутствии/сбое/смене clock. Каталог и renewal используют общий reader; профиль8 scripts/build/lint прошёл. Runtime backend ux-certificates255/frontend ux-certificates251. Следующий256 — повторная реальная issuance + scheduler renewal/fingerprint по уже сохранённому разрешению254, свежий baseline и полный откат; реальный renewal пока не принят. Этап12.5 открыт.
Актуальное продолжение 2026-10-15: 256 — collector renewal использует подтверждённые dates без выдуманного revocation status; профиль/build/lint прошли, backend ux-certificates256/source528/dist1080 healthy. Реальное scheduler renewal выполнилось, served TLS SHA-256 сменился и совпал с новым native leaf, но импорт создал2 одинаковых имени: общая приёмка не завершена. Все own native/DNS/jobs/settings очищены/восстановлены; оба CHR доступны. Следующий257 — запрет ложного success при неоднозначном импорте и стратегия уникальной замены; отдельно лимит REST logins6. Этап12.5 открыт.
| Параметр | Проверенное состояние |
| --- | --- |
@@ -34,6 +34,24 @@ 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.256 — реальный scheduler renewal, дубликаты native имён и полный откат (2026-10-15)
Начат2026-10-14, завершён2026-10-15 по Новосибирску. Пятичасовой лимит сбросился, недельный остался ограниченным. По действующему разрешению254 снят новый native/SQL baseline, own jobs/certificates/DNS0, token/zone/account проверены. Первый UI issue exact mmt253-8e62a941.pngs.top/manual →done, trusted TLS/private-key/native SHA-256 подтверждены. [UI](ux-ui/acceptance/acme256-live-ui.json), [before](ux-ui/acceptance/acme256-tls-before.json).
Native date reader255 теперь правильно даёт validFrom/validUntil в UTC и daysLeft90, совпадающие с X509. Но statusunknown: REST7.24.5 не присылает flags/revoked/expired. Первый enable-triggered run был skipped/renewed0, без нового ACME order; comparator expectation renewed1 не прошёл и сохранён отдельно [skip](ux-ui/acceptance/acme256-renewal-skipped.json). Каталог не должен выдумывать revocation state. Для renewal правило уточнено: достаточно подтверждённого срока и начавшегося непротиворечивого validity window; unknown/missing/changed clock, missing start, future start и reversed window по-прежнему не создают job. Это соответствует прежнему разрешённому renewal даже для explicit revoked/expired, не объявляет сертификат valid.
Collector native-clock→canonical-state→issue тесты: stable offset создаёт одну задачу, changed/missing не создаёт; отсутствующие REST revocation flags с известными dates позволяют renewal, неизвестные/future/reversed dates блокируют. Все8 profile scripts, contracts/backend build, scoped lint passed. Production backend ux-certificates256/source528/compiled1080 совпал, healthy, frontend251/DB/Portal сохранены. Изменённый scope не требовал повтора полной регрессии249.
После исправления один enable-triggered scheduler run (interval86400/threshold90), без run-now: scheduler issue →done, receipt ok/renewed1/errors0, затем enabledfalse до следующего интервала. Реально served TLS сменился с342d36bc… на70b7b9f1… и совпал с новым private-key native leaf; доверие/SNI не отключались. [After](ux-ui/acceptance/acme256-tls-after.json), [jobs](ux-ui/acceptance/acme256-jobs.json), [run](ux-ui/acceptance/acme256-renewal.json).
Приёмка renewal всё равно открыта: /certificate содержит2 leaf с одинаковым logical name mmt253-8e62a941, разными .id/SHA-256 и private-key=true. [Duplicate leaves](ux-ui/acceptance/acme256-duplicate-leaves.json). Next collector отвергнет неоднозначность; import ACK + done не доказывают устойчивую замену. Fresh TLS действительно served new leaf, поэтому не заявляем, что TLS остался старым. До fresh sample ошибочно скопированный вручную fingerprint не прошёл SHA-256 validation; затем использован точный файл native report через SCP. Предусловие statusvalid оказалось неверным для REST flags; первый scheduler run безопасно skipped, после уточнения policy выполнен один реальный order. Не суммируем skip как успешное renewal.
Cleanup сначала столкнулся с REST401/500; точный ответ resource500: too many concurrent logins (6). Временно остановлен только backend, затем восстановлены configured www-ssl/api-ssl, удалены оба own leaf/chain/PEM. Certificates/file stable metadata/configured services/normalized export совпали с fresh baseline; исключены dynamic connections и directory mtime. [Native](ux-ui/acceptance/acme256-native.json). Backend снова запущен и healthy, Portal послеcleanup оба CHR читает безошибочно; пароли не менялись. REST concurrency остаётся отдельным воспроизведённым ограничением.
TXT приложение удалило; own A удалена по exact name/type/content/ID, DNS0 обоихимён [DNS](ux-ui/acceptance/acme256-cloudflare.json). ACME/renew settings восстановлены целиком, scheduler refresh применён, его empty-run metadata затем восстановлена exact SQL compare. Own issue jobs удалены, private token/baseline/helper/SQL файлы удалены с Debian и локальный secret fixture удалён. Historical events/scheduler receipts/CA records сохранены; CA revocation не заявляется.
Следующий257 — post-import подтверждение unique logical name/expected X509 fingerprint/private key перед применением/успехом и безопасная стратегия уникальной замены без потери старого working leaf. Дополнительно проработать per-device REST concurrency/login cap. Эти дефекты не маскируются сообщением successful acceptance; новое разрешение на тот же согласованный сценарий не запрашивается без изменения его риска/объёма.
## 12.5.255 — native даты с подтверждённым offset для каталога и renewal (2026-10-14)
После измерения254 добавлен общий readCertificateRowsWithClock: читает gmt-offset перед каталогом, для native timezone-less дат повторно читает clock после; принимает только одинаковые валидные offsets. Native YYYY-MM-DD HH:mm:ss преобразуется в offset-qualified datetime с проверкой календаря, затем UTC; explicit ISO сохраняет свой offset. Не предполагается UTC/пояс backend/будущий DST. rawValidFrom/rawValidUntil остаются исходными. Отсутствующий/некорректный/сменившийся/недоступный clock сохраняет unknown/null и не обходит renewal guard252; ошибка самого каталога сохраняет error. Legacy старые форматы без надёжного контекста не угадываются.
@@ -0,0 +1,33 @@
{
"date": "2026-10-14",
"block": "12.5.256",
"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
}
@@ -0,0 +1,16 @@
[
{
".id": "*7",
"name": "mmt253-8e62a941",
"common-name": "mmt253-8e62a941.pngs.top",
"fingerprint": "342d36bc13c4f4e807add3833f61b6b70aa4791cbf297bcbef1b0026d22b51a3",
"private-key": "true"
},
{
".id": "*A",
"name": "mmt253-8e62a941",
"common-name": "mmt253-8e62a941.pngs.top",
"fingerprint": "70b7b9f11a77e5e1d21b43074fd84fa334a04bb7e871315eda1739638e8164be",
"private-key": "true"
}
]
+1
View File
@@ -0,0 +1 @@
[{"id" : "5b0aa78a-375d-4b6f-841f-aa8ff189408f", "source" : "manual", "status" : "done", "step" : "done", "serverId" : 2, "certName" : "mmt253-8e62a941", "error" : null}, {"id" : "2abc385b-3dd7-4ef5-b438-679c94d46e0c", "source" : "scheduler", "status" : "done", "step" : "done", "serverId" : 2, "certName" : "mmt253-8e62a941", "error" : null}]
@@ -0,0 +1,35 @@
{
"date": "2026-10-14",
"block": "12.5.256",
"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": "5b0aa78a-375d-4b6f-841f-aa8ff189408f",
"accepted": true,
"job": {
"id": "5b0aa78a-375d-4b6f-841f-aa8ff189408f",
"status": "done",
"step": "done"
},
"uiTerminalConfirmed": true,
"postCleanup": {
"tokenConfigured": false,
"ownJobStatus": 404,
"reachableServerIds": [
"1",
"2"
],
"ownCertificateAbsent": true
}
}
@@ -0,0 +1,10 @@
{
"fqdn": "mmt253-8e62a941.pngs.top",
"certName": "mmt253-8e62a941",
"nativePrivateKey": true,
"nativeFingerprint256": "342d36bc13c4f4e807add3833f61b6b70aa4791cbf297bcbef1b0026d22b51a3",
"rawValidFrom": "2026-10-14 17:51:49",
"rawValidUntil": "2027-01-12 17:51:48",
"clockOffset": "+02:00",
"clockTimeZone": "Europe/Warsaw"
}
+13
View File
@@ -0,0 +1,13 @@
{
"date": "2026-10-15",
"block": "12.5.256",
"certificatesBaselineMatched": true,
"fileStableMetadataBaselineMatched": true,
"directoryLastModifiedExcluded": true,
"configuredServicesBaselineMatched": true,
"dynamicServiceConnectionsExcluded": true,
"normalizedExportMatched": true,
"passwordChanged": false,
"temporaryBackendPauseForLoginLimit": true,
"backendRestartedAfterCleanup": true
}
@@ -0,0 +1,57 @@
{
"date": "2026-10-14",
"block": "12.5.256",
"fqdn": "mmt253-8e62a941.pngs.top",
"enableRequests": 1,
"runNowRequests": 0,
"run": {
"id": "sch-1791996745022-sq19wrmj",
"jobKey": "certificates_renew",
"startedAt": "2026-10-14 16:52:24.191+00",
"finishedAt": "2026-10-14 16:52:25.02+00",
"status": "ok",
"error": null,
"durationMs": 829,
"resultJson": {
"v": 1,
"job": "certificates_renew",
"errors": [],
"checked": 1,
"renewed": 0,
"targets": [
{
"action": "skipped",
"message": "Срок или состояние сертификата не подтверждены. Обновление не выполнялось.",
"certName": "mmt253-8e62a941",
"daysLeft": 90,
"serverId": "2"
}
],
"sampledAt": "2026-10-14T16:52:24.191Z",
"skippedTargets": 1
}
},
"snapshot": {
"v": 1,
"job": "certificates_renew",
"errors": [],
"checked": 1,
"renewed": 0,
"targets": [
{
"action": "skipped",
"message": "Срок или состояние сертификата не подтверждены. Обновление не выполнялось.",
"certName": "mmt253-8e62a941",
"daysLeft": 90,
"serverId": "2"
}
],
"sampledAt": "2026-10-14T16:52:24.191Z",
"skippedTargets": 1
},
"failure": {
"name": "AssertionError",
"message": "Expected values to be strictly equal:\n\n0 !== 1\n"
},
"disabledAfterRun": true
}
@@ -0,0 +1,73 @@
{
"date": "2026-10-15",
"block": "12.5.256",
"fqdn": "mmt253-8e62a941.pngs.top",
"enableRequests": 1,
"runNowRequests": 0,
"eligibility": {
"validFrom": "2026-10-14T15:51:49.000Z",
"validUntil": "2027-01-12T15:51:48.000Z",
"daysLeft": 90,
"revocationStatus": "unknown"
},
"run": {
"id": "sch-1791997029723-ryvhn6y9",
"jobKey": "certificates_renew",
"startedAt": "2026-10-14 16:56:33.978+00",
"finishedAt": "2026-10-14 16:57:09.722+00",
"status": "ok",
"error": null,
"durationMs": 35744,
"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-14T16:56:33.978Z",
"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-14T16:56:33.978Z",
"skippedTargets": 0
},
"disabledAfterRun": true,
"nativeVerification": {
"duplicateLogicalNames": true,
"servedLeafChanged": true,
"newServedLeafMatchesNative": true,
"overallRenewalAccepted": false,
"reason": "Duplicate logical names prevent unambiguous subsequent renewal"
},
"cleanup": {
"nativeBaselineMatched": true,
"sqlSettingsRestored": true,
"ownJobsRemoved": true,
"dnsNamesEmpty": true,
"backendHealthy": true
}
}
@@ -0,0 +1,10 @@
{
"sampledAt": "2026-10-14T16:59:24.292Z",
"fqdn": "mmt253-8e62a941.pngs.top",
"remoteAddress": "104.165.244.7",
"authorized": true,
"fingerprint256": "70:B7:B9:F1:1A:77:E5:E1:D2:1B:43:07:4F:D8:4F:A3:34:A0:4B:B7:E8:71:31:5E:DA:17:39:63:8E:81:64:BE",
"validFrom": "Oct 14 15:58:34 2026 GMT",
"validUntil": "Jan 12 15:58:33 2027 GMT",
"changedFromBefore": true
}
@@ -0,0 +1,15 @@
{
"sampledAt": "2026-10-14T16:52:16.930Z",
"fqdn": "mmt253-8e62a941.pngs.top",
"certName": "mmt253-8e62a941",
"remoteAddress": "104.165.244.7",
"authorized": true,
"hostnameMatched": true,
"protocol": "TLSv1.2",
"fingerprint256": "34:2D:36:BC:13:C4:F4:E8:07:AD:D3:83:3F:61:B6:B7:0A:A4:79:1C:BF:29:7B:CB:EF:1B:00:26:D2:2B:51:A3",
"validFrom": "Oct 14 15:51:49 2026 GMT",
"validUntil": "Jan 12 15:51:48 2027 GMT",
"nativeName": "mmt253-8e62a941",
"nativePrivateKey": true,
"nativeFingerprint256": "342d36bc13c4f4e807add3833f61b6b70aa4791cbf297bcbef1b0026d22b51a3"
}
@@ -0,0 +1,19 @@
{
"date": "2026-10-15",
"block": "12.5.256",
"backendImage": "mmapp-test/backend:ux-certificates256",
"frontendImage": "mmapp-test/frontend:ux-certificates251",
"health": "healthy",
"sourceMatched": 528,
"compiled": {
"matched": 1080,
"missing": 0,
"different": 0
},
"profileScripts": 8,
"profile": "passed",
"build": "passed",
"lint": "passed",
"realRenewalAccepted": false,
"restLoginLimitObserved": 6
}