165 lines
4.8 KiB
Markdown
165 lines
4.8 KiB
Markdown
# docs/roadmap/TASK_014_DEPLOYMENT_DRIFT_REMEDIATION.md
|
||
|
||
Цель:
|
||
|
||
Устранить расхождение между:
|
||
|
||
* Demo Freeze v1;
|
||
* live DetMir runtime.
|
||
|
||
Проверить и внедрить в рабочий контур:
|
||
|
||
* /healthz
|
||
* /readyz
|
||
* /version
|
||
* /metrics
|
||
* request/correlation id
|
||
* Explainable KPI
|
||
* Risk Narrative
|
||
* Executive Action Center
|
||
|
||
Проверить:
|
||
|
||
* почему endpoints дают 404;
|
||
* почему browser conformance падает;
|
||
* почему Executive layer отсутствует;
|
||
* соответствует ли развернутый runtime текущему main;
|
||
* не используется ли устаревший build.
|
||
|
||
Результат:
|
||
|
||
Не добавлять новые функции.
|
||
|
||
Добиться того, чтобы:
|
||
|
||
live runtime == documented runtime
|
||
|
||
и
|
||
|
||
live runtime == Demo Freeze v1
|
||
|
||
````
|
||
|
||
Критерий успеха очень простой:
|
||
|
||
Сегодня:
|
||
|
||
```text
|
||
Browser smoke
|
||
FAIL
|
||
|
||
Production hardening smoke
|
||
FAIL
|
||
````
|
||
|
||
После задачи:
|
||
|
||
```text
|
||
Browser smoke
|
||
PASS
|
||
|
||
Production hardening smoke
|
||
PASS
|
||
```
|
||
|
||
на живом контуре.
|
||
|
||
## Выполнение
|
||
|
||
Дата выполнения: 2026-06-07.
|
||
|
||
Статус: выполнено.
|
||
|
||
### Причина drift
|
||
|
||
Рабочий portal runtime на gateway host был запущен из устаревшего release
|
||
binary. Из-за этого live-контур не соответствовал Demo Freeze v1:
|
||
|
||
* production-hardening endpoints `/healthz`, `/readyz`, `/version`,
|
||
`/metrics` возвращали `404`;
|
||
* отдельные API `/portal/api/workforce/kpi/explain`,
|
||
`/portal/api/risk/narrative`, `/portal/api/actions` возвращали `404`;
|
||
* request/correlation headers отсутствовали на live API;
|
||
* browser conformance smoke видел старый Executive/Workforce/Security слой.
|
||
|
||
Кодовая база при этом уже содержала нужные контракты и UI-блоки. Проблема была
|
||
не в архитектуре и не в отсутствующем функционале, а в несовпадении deployed
|
||
binary с freeze-срезом.
|
||
|
||
### Ремедиация
|
||
|
||
Выполнен controlled deploy актуального release binary на gateway host:
|
||
|
||
* старый бинарник сохранен в backup-каталог на gateway host;
|
||
* новый release binary собран из текущей freeze-ветки;
|
||
* бинарник установлен в штатный путь portal service;
|
||
* `detmir-portal.service` перезапущен;
|
||
* rollback path сохранен через backup старого бинарника.
|
||
|
||
В репозиторий не добавлялись runtime payload, реальные logs, screenshots с
|
||
живыми данными, IP-адреса, hostname, логины, ФИО или подразделения.
|
||
|
||
### Live endpoint matrix после ремедиации
|
||
|
||
Проверено через gateway-local portal port:
|
||
|
||
| Endpoint | Результат |
|
||
| --- | --- |
|
||
| `/healthz` | `200` |
|
||
| `/readyz` | `200` |
|
||
| `/version` | `200` |
|
||
| `/metrics` | `200` |
|
||
| `/portal/api/health` | `200` |
|
||
| `/portal/api/reports?role=executive` | `200` |
|
||
| `/portal/api/workforce/kpi/explain` | `200` |
|
||
| `/portal/api/risk/narrative` | `200` |
|
||
| `/portal/api/actions` | `200` |
|
||
|
||
Также подтверждено:
|
||
|
||
* `X-Request-Id` возвращается;
|
||
* `X-Correlation-Id` возвращается;
|
||
* внешний gateway `/healthz` отвечает `200`;
|
||
* внешний `/portal/` остается закрыт авторизацией;
|
||
* свежий scan journal не показал panic, HTTP 500 или явных timeout.
|
||
|
||
### Smoke results
|
||
|
||
```text
|
||
AWATCH_PORTAL_SMOKE_URL=http://127.0.0.1:18720 \
|
||
node scripts/awatch-production-hardening-smoke.mjs
|
||
PASS
|
||
```
|
||
|
||
```text
|
||
AWATCH_BROWSER_SMOKE_URL=http://127.0.0.1:18720/portal/ \
|
||
AWATCH_BROWSER_SMOKE_ARTIFACT_DIR=/tmp/awatch-live-remediation-browser-smoke \
|
||
node scripts/browser-conformance-smoke.mjs
|
||
PASS
|
||
```
|
||
|
||
```text
|
||
DETMIR_PORTAL_SMOKE_URL=http://127.0.0.1:18720/portal/ \
|
||
node scripts/detmir-portal-tabs-smoke.mjs
|
||
PASS
|
||
```
|
||
|
||
### Test harness hardening
|
||
|
||
`scripts/browser-conformance-smoke.mjs` был усилен: после переключения роли он
|
||
ожидает фактические маркеры контента в `#content`, а не делает снимок через
|
||
фиксированную короткую задержку. Это устраняет ложный FAIL на холодной
|
||
асинхронной загрузке Executive/Security views.
|
||
|
||
Продуктовая бизнес-логика, API contracts, роли, scoring, collectors и
|
||
архитектура не менялись.
|
||
|
||
### Итог
|
||
|
||
```text
|
||
live runtime == documented runtime
|
||
live runtime == Demo Freeze v1
|
||
Browser smoke: PASS
|
||
Production hardening smoke: PASS
|
||
```
|