docs: add enterprise deployment guide

This commit is contained in:
igor04091968
2026-06-07 17:21:09 +03:00
parent 9fa085a53e
commit 3318c89629
10 changed files with 1037 additions and 1 deletions
+16
View File
@@ -187,6 +187,15 @@ collectors.
## Поставка и регистрация
- Enterprise deployment documentation:
[deployment guide](docs/ENTERPRISE_DEPLOYMENT_GUIDE_RU.md),
[topologies](docs/DEPLOYMENT_TOPOLOGIES_RU.md),
[sizing](docs/SIZING_GUIDE_RU.md),
[backup and recovery](docs/BACKUP_AND_RECOVERY_RU.md),
[operations runbook](docs/OPERATIONS_RUNBOOK_RU.md),
[security hardening](docs/SECURITY_HARDENING_RU.md),
[acceptance checklist](docs/ENTERPRISE_ACCEPTANCE_CHECKLIST_RU.md).
- Registry readiness documentation:
[product passport](docs/REGISTRY_PRODUCT_PASSPORT_RU.md),
[architecture](docs/REGISTRY_ARCHITECTURE_RU.md),
@@ -214,6 +223,13 @@ collectors.
- [Коммерческие модули AWatch-rus](docs/DETMIR_COMMERCIAL_MODULES_RU.md)
- [Архитектурный baseline](docs/ARCHITECTURE_BASELINE_RU.md)
- [Пакет пилота для заказчика](docs/CUSTOMER_PILOT_PACK_RU.md)
- [Enterprise deployment guide](docs/ENTERPRISE_DEPLOYMENT_GUIDE_RU.md)
- [Deployment topologies](docs/DEPLOYMENT_TOPOLOGIES_RU.md)
- [Sizing guide](docs/SIZING_GUIDE_RU.md)
- [Backup and recovery](docs/BACKUP_AND_RECOVERY_RU.md)
- [Operations runbook](docs/OPERATIONS_RUNBOOK_RU.md)
- [Security hardening](docs/SECURITY_HARDENING_RU.md)
- [Enterprise acceptance checklist](docs/ENTERPRISE_ACCEPTANCE_CHECKLIST_RU.md)
- [Pilot v1.0](docs/PILOT_V1_RU.md)
- [Pilot v1 demo](docs/PILOT_DEMO_SCENARIO_RU.md)
- [Demo scenario: руководитель](docs/demo/DEMO_SCENARIO_EXECUTIVE_RU.md)
+98
View File
@@ -0,0 +1,98 @@
# Backup and Recovery
Документ описывает базовую модель резервирования и восстановления AWatch-rus.
Конкретный список файлов, баз и services должен уточняться для release profile
и инфраструктуры заказчика.
## Что резервировать
Конфигурация:
- service environment files;
- portal/backend config;
- agent config templates;
- reverse proxy config;
- access control settings;
- deployment inventory templates without secrets in Git.
Данные:
- reports;
- local state;
- telemetry state where applicable;
- evidence metadata;
- investigation/case state;
- readiness bundles;
- release manifests and checksums.
Не хранить в публичном Git:
- passwords;
- tokens;
- private inventory;
- runtime databases;
- customer evidence;
- live screenshots.
## Резервирование конфигурации
Рекомендуемый подход:
1. Хранить sanitized templates в Git.
2. Хранить secrets в защищенном хранилище заказчика.
3. Перед изменениями сохранять текущие service configs.
4. Фиксировать release commit and artifact checksums.
5. Проверять, что rollback path не зависит от ноутбука администратора.
## Резервирование отчетов
Reports and evidence metadata должны резервироваться по политике заказчика.
Минимально:
- daily backup for pilot;
- backup before upgrades;
- separate backup for release manifests;
- restore test before production acceptance.
## Восстановление
Общий порядок:
1. Остановить affected services, если это требуется recovery-планом.
2. Сохранить текущий сбойный state для анализа.
3. Восстановить config/state из backup.
4. Запустить services.
5. Проверить `/healthz`.
6. Проверить `/readyz`.
7. Проверить `/metrics`.
8. Выполнить deployment smoke.
9. Зафиксировать recovery result.
## Rollback после обновления
Перед обновлением:
- сохранить release version;
- сохранить service configs;
- сохранить checksums;
- выполнить smoke baseline;
- подготовить rollback commands.
После rollback:
- проверить portal;
- проверить API reports;
- проверить role gates;
- проверить data freshness;
- зафиксировать причину rollback.
## Ограничения
- Backup не заменяет monitoring.
- Restore должен проверяться до production acceptance.
- Evidence/customer data не должны попадать в публичный repository.
- Demo fixtures не являются production backup.
- Для юридически значимого хранения evidence требуется отдельный контур и
отдельные требования.
+148
View File
@@ -0,0 +1,148 @@
# Deployment Topologies
Документ описывает типовые варианты размещения AWatch-rus.
Все схемы являются ориентировочными. Реальное внедрение должно учитывать
сетевую сегментацию, политики безопасности, объем telemetry и требования к
резервному копированию.
## Standalone
Назначение: локальная экспертиза или demo.
Компоненты:
- один Linux host;
- backend/portal;
- demo fixtures;
- local smoke tooling.
Размещение:
```text
Admin workstation -> local or lab host -> AWatch-rus portal
```
Потоки данных:
- browser -> portal;
- smoke script -> health/readiness/API endpoints;
- demo fixtures -> reports/screenshots.
## Pilot
Назначение: ограниченный показ на выделенном контуре.
Компоненты:
- backend/portal host;
- ограниченная группа endpoint hosts;
- Rust Agent baseline или уже принятые источники;
- reports and readiness checks.
Размещение:
```text
Pilot endpoints -> AWatch-rus backend -> role-based portal
|
+-> reports / evidence materials
```
Потоки данных:
- endpoints -> backend telemetry path;
- backend -> reports;
- browser -> role-based portal;
- operator -> smoke and readiness checks.
## Small Company
Ориентир: до 50 пользователей.
Компоненты:
- один backend/portal host;
- локальное state/report storage;
- reverse proxy with TLS;
- basic backup.
Размещение:
```text
Endpoint group -> backend/portal host -> browser clients
```
Потоки данных:
- endpoint telemetry -> backend;
- backend -> local storage;
- portal -> role views;
- backup job -> backup storage.
## Medium Company
Ориентир: до 250 пользователей.
Компоненты:
- backend/portal host;
- separate storage or dedicated volume;
- reverse proxy;
- monitoring of health/readiness/metrics;
- scheduled backup;
- optional analytics storage where configured.
Размещение:
```text
Endpoint groups -> backend/API host -> storage
-> portal/reports
-> monitoring
```
Потоки данных:
- endpoint telemetry -> backend/API;
- backend -> storage and report layer;
- monitoring -> `/healthz`, `/readyz`, `/metrics`;
- operator -> smoke scripts and runbooks.
## Enterprise
Ориентир: более 250 пользователей, несколько подразделений или строгие
эксплуатационные требования.
Компоненты:
- выделенный backend/API host;
- portal/reverse proxy layer;
- dedicated storage and backup profile;
- monitoring and log collection;
- access control;
- documented rollback;
- optional integrations only after acceptance.
Размещение:
```text
Endpoint segments -> backend/API -> storage/reporting
-> portal via reverse proxy
-> monitoring/logging
-> backup target
```
Потоки данных:
- telemetry -> backend/API;
- backend/API -> storage/reporting;
- portal users -> reverse proxy -> portal;
- monitoring -> health/readiness/metrics;
- backup -> backup target.
## Общие правила
- Не размещать secrets в repository.
- Не публиковать portal без TLS и access control.
- Не включать optional addon как production source без acceptance.
- Не использовать demo fixtures как production data.
- Не делать sizing claims без load validation.
@@ -0,0 +1,72 @@
# Enterprise Acceptance Checklist
Чеклист используется для приемки enterprise/pilot deployment AWatch-rus.
## Установка
- [ ] Release commit/tag зафиксирован.
- [ ] Release artifacts получены из утвержденного источника.
- [ ] Checksums проверены.
- [ ] Secrets не хранятся в Git.
- [ ] Deployment profile согласован.
- [ ] Optional integrations перечислены отдельно.
## Запуск
- [ ] Backend/portal service запущен.
- [ ] Reverse proxy настроен, если используется.
- [ ] TLS настроен, если portal доступен по сети.
- [ ] Required storage доступен.
- [ ] systemd services/timers активны where applicable.
## Доступность API
- [ ] `/healthz` отвечает.
- [ ] `/readyz` отвечает.
- [ ] `/metrics` отвечает.
- [ ] `/api/reports?role=executive` отвечает.
- [ ] `/api/actions?role=executive` отвечает.
- [ ] Role gates не отдают лишние данные.
## Портал
- [ ] Portal открывается.
- [ ] Role `Руководитель` показывает главный вывод.
- [ ] Role `Безопасность` показывает ИБ-контур.
- [ ] Role `Расследования` показывает investigation/evidence flow.
- [ ] Role `Админ` показывает readiness/operations view.
- [ ] Ошибки API отображаются контролируемо.
## Smoke
- [ ] `scripts/deployment-readiness-smoke.mjs` проходит.
- [ ] Production hardening smoke проходит.
- [ ] Pilot demo smoke проходит, если выполняется demo.
- [ ] Smoke results сохранены в acceptance evidence.
## Документация
- [ ] Enterprise deployment guide доступен.
- [ ] Topologies documented.
- [ ] Sizing assumptions documented.
- [ ] Backup and recovery documented.
- [ ] Operations runbook documented.
- [ ] Security hardening documented.
- [ ] Registry readiness docs доступны.
- [ ] Demo pack доступен.
## Резервирование
- [ ] Config backup настроен.
- [ ] Reports/state backup настроен.
- [ ] Evidence metadata backup настроен, если используется.
- [ ] Restore test выполнен.
- [ ] Rollback process documented.
## Ограничения
- [ ] Не заявляется полноценная DLP/SIEM/EDR.
- [ ] Не заявляется ML/LLM scoring.
- [ ] Optional integrations не показаны как implemented без приемки.
- [ ] pfSense не заявлен как обязательный source.
- [ ] Demo data не смешаны с production data.
+127
View File
@@ -0,0 +1,127 @@
# Enterprise Deployment Guide
Документ описывает варианты внедрения AWatch-rus в инфраструктуре заказчика.
Граница: документ не добавляет новую функциональность и не заявляет
неподтвержденные collectors. Конкретная поставка должна фиксировать фактически
включенные источники, версии и smoke-результаты.
## Архитектура развертывания
Базовая схема:
```text
Endpoint hosts / existing telemetry sources
|
v
AWatch-rus backend and ActivityWatch-compatible data layer
|
+--> role-based portal
+--> JSON API contracts
+--> reports and Markdown exports
+--> readiness, health and metrics endpoints
+--> optional integrations where configured
```
Основные компоненты:
- Rust backend and portal runtime;
- Rust Agent baseline;
- ActivityWatch-compatible telemetry layer;
- role-based portals: `executive`, `manager`, `security`, `forensics`, `admin`;
- reports and evidence materials;
- readiness/smoke tooling;
- optional storage/integration components where configured.
## Минимальная инсталляция
Назначение: локальная проверка, demo или первичная экспертиза.
Компоненты:
- AWatch-rus backend/portal;
- demo dataset;
- screenshots and demo report;
- local smoke scripts.
Не требуется:
- массовая установка агентов;
- production ingestion;
- pfSense integration;
- external SIEM/syslog.
Ограничение: минимальная инсталляция не доказывает production sizing и не
заменяет пилот на данных заказчика.
## Пилотная инсталляция
Назначение: ограниченная проверка ценности на согласованном контуре.
Компоненты:
- backend/portal on-premise;
- Rust Agent baseline или уже принятые источники;
- Workforce KPI and Explainable KPI;
- UEBA Score v1;
- Risk Narrative;
- Executive Action Center;
- reports and smoke checks.
Пилот должен фиксировать:
- список включенных источников;
- период сбора;
- coverage expectations;
- ответственных за эксплуатацию;
- fallback режимы;
- критерии приемки.
## Рекомендуемая инсталляция
Назначение: регулярный промышленный мониторинг.
Рекомендуемый профиль:
- выделенный Linux host или VM/LXC для backend/portal;
- systemd-managed services;
- reverse proxy with TLS;
- отдельное хранилище для state/reports/evidence metadata;
- регулярный backup;
- мониторинг `/healthz`, `/readyz`, `/metrics`;
- smoke после обновления и перед демонстрацией;
- ограниченный административный доступ;
- documented rollback plan.
## Optional integrations
Опциональные компоненты:
- pfSense as optional addon / `contract_only`, если ingestion отдельно не
включен и не принят;
- 1C analytics where configured;
- AD/LDAP as planned or deployment-specific integration;
- SIEM/syslog as future or deployment-specific integration;
- external storage where required by customer policy.
Optional не означает обязательную зависимость AWatch-rus core.
## Ограничения
AWatch-rus deployment guide не заявляет:
- полноценную DLP;
- полноценную SIEM;
- EDR/XDR;
- ML/LLM scoring;
- auto-remediation without manual control;
- готовый universal agentless provider для любой инфраструктуры.
## Связанные документы
- [DEPLOYMENT_TOPOLOGIES_RU.md](DEPLOYMENT_TOPOLOGIES_RU.md)
- [SIZING_GUIDE_RU.md](SIZING_GUIDE_RU.md)
- [BACKUP_AND_RECOVERY_RU.md](BACKUP_AND_RECOVERY_RU.md)
- [OPERATIONS_RUNBOOK_RU.md](OPERATIONS_RUNBOOK_RU.md)
- [SECURITY_HARDENING_RU.md](SECURITY_HARDENING_RU.md)
- [ENTERPRISE_ACCEPTANCE_CHECKLIST_RU.md](ENTERPRISE_ACCEPTANCE_CHECKLIST_RU.md)
+148
View File
@@ -0,0 +1,148 @@
# Operations Runbook
Документ описывает базовые эксплуатационные проверки AWatch-rus.
## Быстрая проверка
Проверить доступность:
```bash
curl -fsS http://<AWATCH_HOST>/healthz
curl -fsS http://<AWATCH_HOST>/readyz
curl -fsS http://<AWATCH_HOST>/metrics
```
Для защищенного reverse proxy использовать утвержденный URL и способ
аутентификации заказчика.
## healthz
`/healthz` используется для проверки, что процесс backend/portal отвечает.
Ожидается:
- HTTP 200 for healthy process;
- structured JSON or text according to current service implementation;
- no secrets in response.
## readyz
`/readyz` используется для проверки готовности обслуживать traffic.
Ожидается:
- ready status only when critical dependencies are acceptable;
- degraded status when reports/data sources are degraded;
- no false fully healthy status for degraded reports.
## metrics
`/metrics` используется для технического мониторинга.
Проверять:
- request counters;
- latency where exposed;
- degraded report counters where exposed;
- error counters.
## Smoke
Базовые smoke scripts:
```bash
node scripts/awatch-production-hardening-smoke.mjs
node scripts/detmir-pilot-demo-smoke.mjs
node scripts/deployment-readiness-smoke.mjs
```
Smoke должен выполняться:
- после установки;
- после обновления;
- перед demo;
- после recovery.
## Журналирование
Проверять:
```bash
journalctl -u <AWATCH_SERVICE> --since "30 minutes ago" --no-pager
systemctl status <AWATCH_SERVICE> --no-pager
systemctl --failed --no-pager
```
Не публиковать в issue/README:
- secrets;
- live hostnames;
- private IPs;
- customer evidence;
- user identifiers.
## Типовые сбои
### Portal недоступен
Проверить:
- process/service status;
- reverse proxy;
- firewall;
- TLS certificate;
- bind address;
- recent logs.
### Reports degraded
Проверить:
- data source freshness;
- worktime/report API timeout;
- stale cache usage;
- coverage;
- errors in logs.
### Нет данных
Проверить:
- выбранный период;
- source availability;
- agent heartbeat;
- expected nodes;
- ingestion/storage status.
### Ролевая ошибка доступа
Проверить:
- selected role;
- `X-AWatch-Role` header where used;
- portal role gates;
- API endpoint scope.
## Диагностика
Минимальный набор:
```bash
curl -i http://<AWATCH_HOST>/healthz
curl -i http://<AWATCH_HOST>/readyz
curl -i http://<AWATCH_HOST>/api/reports?role=executive
curl -i http://<AWATCH_HOST>/api/actions?role=executive
```
Для production использовать TLS endpoint and approved auth.
## Эскалация
Эскалировать, если:
- `/healthz` недоступен;
- `/readyz` постоянно degraded;
- reports timeout повторяется;
- source freshness ниже пилотного SLA;
- backup restore не проходит;
- role gate отдает лишние данные.
+92
View File
@@ -0,0 +1,92 @@
# Security Hardening
Документ описывает базовые меры hardening для AWatch-rus deployment.
Это не сертификационная модель угроз и не заявление о готовности как СЗИ.
## TLS
Рекомендуется:
- публиковать portal только через TLS;
- использовать certificate lifecycle process;
- отключать устаревшие протоколы;
- проверять expiry до demo/production use;
- хранить private keys вне repository.
## Reverse Proxy
Reverse proxy должен:
- завершать TLS;
- ограничивать public exposure;
- передавать только необходимые routes;
- добавлять security headers where policy allows;
- вести access logs без secrets.
## Firewall
Рекомендуется:
- открыть только необходимые ports;
- ограничить admin endpoints;
- запретить прямой доступ к backend, если используется reverse proxy;
- фиксировать правила в deployment documentation;
- проверять правила после изменений.
## Учетные записи
Рекомендуется:
- отдельные service accounts;
- минимально необходимые права;
- запрет shared admin credentials;
- регулярная ротация secrets;
- хранение secrets в защищенном хранилище заказчика.
## Права доступа
Проверять:
- role-based portal access;
- server-side role gates;
- access to evidence materials;
- admin-only operations;
- file permissions for config/state/evidence metadata.
## Журналирование
Логи должны помогать диагностике, но не раскрывать:
- passwords;
- tokens;
- private keys;
- customer evidence;
- персональные данные без необходимости.
## Backup Security
Backup storage должен:
- быть доступен только ответственным ролям;
- хранить encrypted backups where required;
- иметь restore test;
- не публиковаться в Git.
## Demo and Public Materials
Для публичных материалов:
- использовать только demo fixtures;
- использовать TEST-NET addresses for network examples;
- не публиковать live screenshots;
- не публиковать customer hostnames, users, domains or evidence.
## Ограничения
AWatch-rus hardening guide не заявляет:
- сертифицированную защиту информации;
- полноценную DLP/SIEM/EDR;
- автоматическое предотвращение всех инцидентов;
- юридически гарантированную неизменность evidence.
+97
View File
@@ -0,0 +1,97 @@
# Sizing Guide
Документ дает ориентиры для планирования AWatch-rus deployment.
Важно: оценки являются предварительными и требуют проверки на инфраструктуре
заказчика. Нагрузка зависит от частоты событий, периода хранения, числа
источников, объема reports/evidence и выбранных integrations.
## До 50 пользователей
Профиль:
- standalone или small pilot;
- один backend/portal host;
- локальное state/report storage;
- базовый backup.
Ориентиры:
- начать с минимальной инсталляции;
- включать только согласованные источники;
- выполнить smoke and readiness checks;
- проверить, что reports строятся без timeout.
## До 250 пользователей
Профиль:
- dedicated backend/portal host;
- отдельный storage volume;
- reverse proxy with TLS;
- регулярный backup;
- monitoring `/healthz`, `/readyz`, `/metrics`.
Ориентиры:
- валидировать retention policy;
- ограничивать тяжелые report queries;
- проверять data freshness;
- фиксировать coverage expectations.
## До 1000 пользователей
Профиль:
- отдельный backend/API host;
- выделенное storage profile;
- monitoring and alerting;
- staged rollout by departments;
- documented backup/restore;
- smoke after each rollout wave.
Ориентиры:
- проводить load validation;
- проверять report cache/fallback behavior;
- разделять pilot/demo data и production data;
- контролировать очереди/spool на agents;
- учитывать storage growth for evidence metadata.
## Более 1000 пользователей
Профиль:
- enterprise architecture review required;
- staged deployment;
- выделенный storage and backup design;
- monitoring/SLO;
- access control review;
- integration acceptance for each optional addon;
- capacity testing before production rollout.
Ориентиры:
- не переносить pilot sizing автоматически;
- проводить нагрузочные и recovery проверки;
- оценивать retention and backup windows;
- фиксировать ownership of each source;
- использовать rollback plan for rollout waves.
## Факторы нагрузки
- число endpoint hosts;
- частота telemetry events;
- период хранения;
- количество role-based report users;
- объем evidence metadata;
- наличие screenshots/evidence в конкретном контуре;
- optional integrations;
- частота smoke/readiness checks.
## Что нельзя заявлять
- гарантированную производительность без проверки;
- универсальное sizing правило для всех заказчиков;
- готовность optional integrations без отдельной приемки;
- отсутствие необходимости backup/recovery тестов.
@@ -202,4 +202,68 @@ scripts/deployment-readiness-smoke.*
6. Runbook.
7. Acceptance checklist.
8. Проверки.
9. Ограничения.
9. Ограничения.
## Выполнение
Статус: done.
Созданные документы:
- `docs/ENTERPRISE_DEPLOYMENT_GUIDE_RU.md`;
- `docs/DEPLOYMENT_TOPOLOGIES_RU.md`;
- `docs/SIZING_GUIDE_RU.md`;
- `docs/BACKUP_AND_RECOVERY_RU.md`;
- `docs/OPERATIONS_RUNBOOK_RU.md`;
- `docs/SECURITY_HARDENING_RU.md`;
- `docs/ENTERPRISE_ACCEPTANCE_CHECKLIST_RU.md`.
Созданный smoke:
- `scripts/deployment-readiness-smoke.mjs`.
Обновленные документы:
- `README.md`;
- `docs/roadmap/TASK_009_ENTERPRISE_DEPLOYMENT_GUIDE.md`.
Deployment scenarios:
- standalone;
- pilot;
- small company;
- medium company;
- enterprise.
Sizing assumptions:
- до 50 пользователей;
- до 250 пользователей;
- до 1000 пользователей;
- более 1000 пользователей;
- все оценки требуют проверки на инфраструктуре заказчика.
Backup model:
- config backup;
- reports/state backup;
- evidence metadata backup where used;
- restore test;
- rollback after upgrade.
Runbook:
- `/healthz`;
- `/readyz`;
- `/metrics`;
- smoke;
- logs;
- типовые сбои;
- диагностика.
Ограничения:
- новый продуктовый код, API, агенты и UI не добавлялись;
- ML/LLM не добавлялись;
- новые security claims не добавлялись;
- sizing не заявлен как гарантия без валидации.
+174
View File
@@ -0,0 +1,174 @@
#!/usr/bin/env node
import fs from "node:fs";
import path from "node:path";
import process from "node:process";
import { fileURLToPath } from "node:url";
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const requiredDocs = [
"docs/ENTERPRISE_DEPLOYMENT_GUIDE_RU.md",
"docs/DEPLOYMENT_TOPOLOGIES_RU.md",
"docs/SIZING_GUIDE_RU.md",
"docs/BACKUP_AND_RECOVERY_RU.md",
"docs/OPERATIONS_RUNBOOK_RU.md",
"docs/SECURITY_HARDENING_RU.md",
"docs/ENTERPRISE_ACCEPTANCE_CHECKLIST_RU.md",
];
const requiredScreenshots = [
"docs/screenshots/01-executive-overview.png",
"docs/screenshots/02-risk-heatmap.png",
"docs/screenshots/03-security-view.png",
"docs/screenshots/04-operations-view.png",
"docs/screenshots/05-investigation-pack.png",
"docs/screenshots/06-markdown-report.png",
"docs/screenshots/07-product-architecture.png",
];
const requiredRoadmap = [
"docs/roadmap/TASK_009_ENTERPRISE_DEPLOYMENT_GUIDE.md",
];
const requiredRegistryDocs = [
"docs/REGISTRY_PRODUCT_PASSPORT_RU.md",
"docs/REGISTRY_ARCHITECTURE_RU.md",
"docs/REGISTRY_FUNCTIONAL_SCOPE_RU.md",
"docs/REGISTRY_DEPENDENCY_STATEMENT_RU.md",
"docs/REGISTRY_DEPLOYMENT_MODEL_RU.md",
"docs/REGISTRY_COMMERCIAL_POSITIONING_RU.md",
"docs/REGISTRY_READINESS_CHECKLIST_RU.md",
];
const requiredDemoDocs = [
"docs/PILOT_DEMO_SCENARIO_RU.md",
"docs/DEMO_RUNBOOK_RU.md",
"docs/DEMO_REPORT_EXAMPLE_RU.md",
"docs/PILOT_VALUE_PROPOSITION_RU.md",
"docs/demo/DEMO_SCENARIO_EXECUTIVE_RU.md",
"docs/demo/DEMO_SCENARIO_SECURITY_RU.md",
"docs/demo/DEMO_SCENARIO_FORENSICS_RU.md",
"docs/fixtures/pilot-v1-demo/demo-seed-data.json",
];
function exists(file) {
return fs.existsSync(path.join(root, file));
}
function fileText(file) {
return fs.readFileSync(path.join(root, file), "utf8");
}
function checkFiles(files) {
return files.filter((file) => !exists(file));
}
function checkScreenshots(files) {
const bad = [];
for (const file of files) {
const fullPath = path.join(root, file);
if (!fs.existsSync(fullPath)) {
bad.push({ file, reason: "missing" });
continue;
}
const bytes = fs.readFileSync(fullPath);
const png = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);
if (bytes.length <= 1000 || !bytes.subarray(0, 8).equals(png)) {
bad.push({ file, reason: "not_png_or_too_small", size: bytes.length });
}
}
return bad;
}
function checkMarkdownLinks(files) {
const findings = [];
const linkPattern = /!?\[[^\]]+\]\(([^)]+)\)/g;
for (const file of files) {
if (!file.endsWith(".md")) continue;
let match = null;
const text = fileText(file);
while ((match = linkPattern.exec(text)) !== null) {
const raw = String(match[1] || "").trim();
const target = raw.split(/\s+/)[0].replace(/^<|>$/g, "");
if (!target || target.startsWith("#") || target.startsWith("http://") || target.startsWith("https://") || target.startsWith("mailto:")) {
continue;
}
const withoutAnchor = target.split("#", 1)[0];
if (!withoutAnchor) continue;
const resolved = path.resolve(root, path.dirname(file), withoutAnchor);
if (!fs.existsSync(resolved)) {
findings.push({ file, target });
}
}
}
return findings;
}
function checkSensitiveStrings(files) {
const patterns = [
/SHARKON2025/i,
/10\.10\.10\./,
/192\.168\./,
/172\.(1[6-9]|2\d|3[0-1])\./,
/dm\.iri/i,
/\/home\/igor/i,
/lk\.mts\.ru/i,
/l\.mts\.ru/i,
/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/i,
];
const findings = [];
for (const file of files) {
if (!file.endsWith(".md") && !file.endsWith(".json") && !file.endsWith(".mjs")) continue;
const text = fileText(file);
for (const pattern of patterns) {
if (pattern.test(text)) findings.push({ file, pattern: String(pattern) });
}
}
return findings;
}
function pass(checks, name, ok, details = {}) {
checks.push({ name, ok: Boolean(ok), ...details });
}
function main() {
const checks = [];
const allDocs = [
...requiredDocs,
...requiredRoadmap,
...requiredRegistryDocs,
...requiredDemoDocs,
"README.md",
];
const missingDocs = checkFiles(requiredDocs);
pass(checks, "deployment_docs_exist", missingDocs.length === 0, { missing: missingDocs });
const missingRoadmap = checkFiles(requiredRoadmap);
pass(checks, "roadmap_exists", missingRoadmap.length === 0, { missing: missingRoadmap });
const missingRegistryDocs = checkFiles(requiredRegistryDocs);
pass(checks, "registry_docs_exist", missingRegistryDocs.length === 0, { missing: missingRegistryDocs });
const missingDemoDocs = checkFiles(requiredDemoDocs);
pass(checks, "demo_docs_exist", missingDemoDocs.length === 0, { missing: missingDemoDocs });
const screenshotProblems = checkScreenshots(requiredScreenshots);
pass(checks, "screenshots_exist_and_are_png", screenshotProblems.length === 0, { findings: screenshotProblems });
const linkProblems = checkMarkdownLinks(allDocs);
pass(checks, "markdown_links_valid", linkProblems.length === 0, { findings: linkProblems });
const sensitiveFindings = checkSensitiveStrings(allDocs);
pass(checks, "sensitive_string_scan", sensitiveFindings.length === 0, { findings: sensitiveFindings });
const ok = checks.every((check) => check.ok);
process.stdout.write(`${JSON.stringify({
ok,
generated_at_utc: new Date().toISOString(),
checks,
}, null, 2)}\n`);
process.exitCode = ok ? 0 : 2;
}
main();