Files
AWatch-rus/docs/OPENCODE_SYSTEM_READINESS_AUDIT_RU.md
T

206 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Readiness Audit: handover plan vs codebase reality
**Дата:** 2026-06-11
**Метод:** read-only audit всех entrypoints из handover-плана + AGENTS.md + файловая система.
**Правило:** ничего не менять, не деплоить, не коммитить.
---
## Executive Summary
Handover-план (613 строк) в целом соответствует кодовой базе: все ключевые
компоненты существуют. Найдено 5 расхождений между планом и реальностью,
1 missing-позиция (некритична). Первичный вывод про `clickhouse-1c/ai/` был ложным: директория существует.
Inventory.ini содержит **production credentials в открытом виде**. Значения в
этом отчете намеренно не фиксируются; это единственный критический blocker.
Ниже — детальная таблица по каждому слою.
---
## Полная таблица проверки
| # | Слой | Функционал (из handover) | Файл/модуль/команда | Проверка | Статус | Что делать дальше |
|---|------|--------------------------|---------------------|----------|--------|-------------------|
| 1 | **AW server** | `activitywatch-server` на `:5600` | `aw-server/activitywatch-server.service` | Файл существует | OK | — |
| 2 | AW server | WebUI + CORS | `aw-server/` (общий деплой) | Ansible `deploy_aw_server.yml` разворачивает | OK | — |
| 3 | AW server | SQLite не перегружен | `adk-rust/crates/aw-db-maintenance/` | Крейт существует | OK | — |
| 4 | AW server | RU patch v5 | `aw-server/aw-ru-patch.js` → деплоится как `ru-patch-v5.js` | Ansible line 450 маппит aw-ru-patch.js → ru-patch-v5.js | OK | В handover-плане (строка 185) curl проверяет `/js/ru-patch-v5.js` — это корректный URL после деплоя, но файла `ru-patch-v5.js` в репозитории нет, только `aw-ru-patch.js` |
| 5 | AW server | Host sanitize script | `aw-server/aw-host-sanitize.js` | Существует | OK | — |
| 6 | AW server | Worktime panel | `aw-server/aw-worktime-panel.js` | Существует | OK | — |
| 7 | **Windows/RDP** | `deploy-ensemble.ps1` | `windows/deploy-ensemble.ps1` | Существует | OK | — |
| 8 | Windows/RDP | `validate-deployment.ps1` | `windows/validate-deployment.ps1` | Существует | OK | — |
| 9 | Windows/RDP | `deployment-config.json` | Нет в репозитории (runtime-файл на Windows) | Созётся скриптами, упоминается в 120+ местах | OK | Ожидаемое поведение: файл генерируется на хосте |
| 10 | Windows/RDP | Scheduled Tasks `ActivityWatch Launch/Recovery` | `windows/install-collector-guard-service.ps1`, `windows/aw-collector-guard.ps1` | Скрипты существуют | OK | — |
| 11 | Windows/RDP | Rust collector guard (C# service) | `windows/AWatchRusCollectorGuardService.cs` | Существует | OK | — |
| 12 | Windows/RDP | PowerShell fallback | `windows/aw-collector-guard.ps1` | Существует | OK | — |
| 13 | Windows/RDP | Все DLP-коллекторы | `windows/dlp-endpoint-signals-collector.ps1`, `file-operations-collector.ps1`, `browser-domains-native-collector.ps1`, `email-outbound-collector.ps1`, `dlp-policy-client.ps1` | Все существуют | OK | — |
| 14 | Windows/RDP | Worktime session collector | `windows/worktime-session-collector.ps1` | Существует | OK | — |
| 15 | Windows/RDP | Evidence sync | `windows/sync-dlp-evidence-artifacts.ps1` | Существует | OK | — |
| 16 | Windows/RDP | Общий PowerShell module | `windows/ActivityWatch.Windows.Common.psm1` (2667 строк) | Существует | OK | — |
| 17 | Windows/RDP | InnoSetup install kit | `windows/installkit/innosetup/` | Существует c filelist | OK | — |
| 18 | **Worktime API** | `aw-worktime-api` на `:5610` | `adk-rust/crates/worktime-api/` + `aw-server/aw-worktime-api.service` | Крейт + service существует | OK | — |
| 19 | Worktime API | `/health` endpoint | В коде worktime-api | Есть | OK | — |
| 20 | Worktime API | `/reports/worktime/management` | В коде worktime-api | Есть | OK | — |
| 21 | Worktime API | stale cache | В коде worktime-api | Есть | OK | — |
| 22 | Worktime API | Prewarm | `aw-server/aw-worktime-prewarm.sh` + `aw-server/aw-worktime-prewarm.service` + `.timer` | Существует | OK | — |
| 23 | **DLP** | Policy engine Rust | `adk-rust/crates/dlp-policy-engine/` + `aw-server/dlp-policy-engine/dlp-policy-engine.service` | Существует | OK | — |
| 24 | DLP | Case management Rust | `adk-rust/crates/dlp-case-management/` + `aw-server/dlp-case-management/case-service.service` | Существует | OK | — |
| 25 | DLP | Compliance Rust | `adk-rust/crates/dlp-compliance/` + `aw-server/dlp-compliance/report-scheduler.service` | Существует | OK | — |
| 26 | DLP | Content analyzer (Python) | `aw-server/dlp-content-analysis/` | Существует (Python) | OK | В AGENTS.md Python разрешён именно для этого |
| 27 | DLP | DLP health check | `adk-rust/crates/dlp-health-check/` | Существует | OK | — |
| 28 | DLP | DLP Influx exporter | `adk-rust/crates/dlp-influx-exporter/` + `aw-server/aw-dlp-influx-exporter.service` | Существует | OK | — |
| 29 | DLP | DLP admin CLI | `adk-rust/crates/dlp-admin-cli/` | Существует | OK | — |
| 30 | DLP | DLP aggregator | `adk-rust/crates/dlp-aggregator/` | Существует | OK | — |
| 31 | DLP | DLP CEF exporter | `adk-rust/crates/dlp-cef-exporter/` | Существует | OK | — |
| 32 | DLP | DLP webhook sender | `adk-rust/crates/dlp-webhook-sender/` | Существует | OK | — |
| 33 | DLP | DLP syslog forwarder | `adk-rust/crates/dlp-syslog-forwarder/` | Существует | OK | — |
| 34 | **WebUI** | RU patch подключён | Ansible `deploy_aw_server.yml` + `apply_webui_ru_patch.sh` | Работает через Ansible | OK | — |
| 35 | WebUI | Host sanitize подключён | Ansible деплоит `aw-host-sanitize.js` | Есть | OK | — |
| 36 | WebUI | browser cache | Cache-bust через `aw_ru_patch_cache_bust` в Ansible | Есть | OK | — |
| 37 | **Portal** | Порт `:8720` | `detmir-portal/src/main.rs` строка 161: `default_value = "127.0.0.1:8720"` | Совпадает с handover | OK | — |
| 38 | Portal | `/api/health` | `main.rs` строка 1517 | Есть | OK | — |
| 39 | Portal | `/api/reports` | `main.rs` строка 1583 | Есть | OK | — |
| 40 | Portal | Read-only | Заявлено как read-only в коде | OK | OK | — |
| 41 | Portal | Role views | PortalRole enum, role filtering | Есть | OK | — |
| 42 | Portal | HTML static SPA | `detmir-portal/src/static/index.html` + `app.js` | Есть | OK | — |
| 43 | Portal | Документация | `docs/PORTAL_RU.md` | Существует | OK | — |
| 44 | **Grafana/Influx** | Dashboards в `grafana/` | `grafana/detmir-aw-main-dashboard.json`, `detmir-rdp-user-activity-dashboard.json`, `detmir-dlp-security-dashboard.json`, `dlp-dashboard.json`, `detmir-dlp-management-dashboard.json`, `pfsense-loki-dashboard.json` | 6 файлов | OK | Handover план говорит `grafana/`, но реальность — плоские JSON без provisioning-структуры |
| 45 | Grafana/Influx | Influx exporters | `aw-server/aw-worktime-influx-exporter.service` + `aw-server/aw-dlp-influx-exporter.service` + соответствующие Rust крейты | Существуют | OK | — |
| 46 | Grafana/Influx | `deploy_grafana_check.yml` | `ansible/deploy_grafana_check.yml` | Существует | OK | — |
| 47 | Grafana/Influx | `deploy_grafana_dashboards.yml` | `ansible/deploy_grafana_dashboards.yml` | Существует (НЕ упомянут в handover) | NEEDS_VERIFICATION | Handover не упоминает этот playbook, но он существует |
| 48 | Grafana/Influx | `grafana-1c/` отдельный стек | `grafana-1c/docker-compose.yml`, `grafana-1c/grafana/dashboards/*.json` | Существует для 1C MSSQL/Postgres | OK | Handover не выделяет отдельный стек grafana-1c |
| 49 | **ClickHouse/1C** | Docker Compose | `clickhouse-1c/docker-compose.yml` | Существует | OK | — |
| 50 | ClickHouse/1C | Init SQL (6 файлов) | `clickhouse-1c/clickhouse/init/00_database.sql` `05_financial_reporting.sql` | Все 6 существуют | OK | — |
| 51 | ClickHouse/1C | Detection SQL | `clickhouse-1c/detections/insert_detections.sql`, `build_entity_timeline.sql`, `open_cases_from_detections.sql` | Все 3 существуют | OK | — |
| 52 | ClickHouse/1C | ETL Python | `clickhouse-1c/etl/*.py` | 6 Python-файлов | OK | — |
| 53 | ClickHouse/1C | Grafana 1C dashboards | `clickhouse-1c/grafana/provisioning/dashboards/files/*.json` | 10 dashboard JSON | OK | — |
| 54 | ClickHouse/1C | Grafana datasource | `clickhouse-1c/grafana/provisioning/datasources/clickhouse.yml` | Существует | OK | — |
| 55 | ClickHouse/1C | Ingest Rust | `adk-rust/crates/aw-1c-ingest/` | Существует | OK | — |
| 56 | ClickHouse/1C | landing каталоги | Не в репозитории (runtime-директории) | mkdir в handover step 6.3 | OK | Создаются при bootstrap |
| 57 | **Gateway** | Proxmox web gateway | `ansible/deploy_proxmox_web_gateway.yml` | Существует | OK | — |
| 58 | **Rust crates** | Все целевые крейты | 56 членов workspace в `adk-rust/Cargo.toml` | Все `Cargo.toml` найдены | OK | — |
| 59 | Rust crates | Quality gate | `adk-rust/crates/quality-gate/` + `scripts/quality-gate.sh` | Существует | OK | — |
| 60 | **Ansible** | `deploy_aw_server.yml` | `ansible/deploy_aw_server.yml` | Существует | OK | — |
| 61 | Ansible | `deploy_aw_windows.yml` | `ansible/deploy_aw_windows.yml` | Существует | OK | — |
| 62 | Ansible | `deploy_detmir_portal.yml` | `ansible/deploy_detmir_portal.yml` | Существует | OK | — |
| 63 | Ansible | `deploy_proxmox_web_gateway.yml` | `ansible/deploy_proxmox_web_gateway.yml` | Существует | OK | — |
| 64 | Ansible | `deploy_grafana_check.yml` | `ansible/deploy_grafana_check.yml` | Существует | OK | — |
| 65 | Ansible | `inventory.ini` | `ansible/inventory.ini` | Существует | **⚠️ CREDENTIALS LEAK** | Plaintext credentials detected; values redacted |
| 66 | Ansible | `inventory.example.ini` | `ansible/inventory.example.ini` | Существует | OK | — |
| 67 | **Docs/runbooks** | `adk-rust/RUNBOOK.md` | Существует | OK | OK | — |
| 68 | Docs/runbooks | `docs/preparation.md` | Существует | OK | OK | — |
| 69 | Docs/runbooks | `docs/deployment.md` | Существует | OK | OK | — |
| 70 | Docs/runbooks | `docs/runbook.md` | Существует | OK | OK | — |
| 71 | Docs/runbooks | `docs/operations.md` | Существует | OK | OK | — |
| 72 | Docs/runbooks | `docs/windows/deployment.md` | Существует | OK | OK | — |
| 73 | Docs/runbooks | `docs/OPERATIONS_RUNBOOK_WORKTIME_RU.md` | Существует | OK | OK | — |
| 74 | Docs/runbooks | `docs/GRAFANA_DASHBOARDS_RU.md` | Существует | OK | OK | — |
| 75 | Docs/runbooks | `docs/PORTAL_RU.md` | Существует | OK | OK | — |
| 76 | Docs/runbooks | `clickhouse-1c/README.md` | Существует | OK | OK | — |
| 77 | **Root scripts** | `check-aw-data.sh` (Rust wrapper) | Существует (shell → Rust fallback) | OK | OK | — |
| 78 | Root scripts | `check-aw-full.sh` (Rust wrapper) | Существует (shell → Rust fallback) | OK | OK | — |
| 79 | Root scripts | `scripts/prod_rollout.sh` | Существует | OK | OK | — |
---
## Найденные противоречия
### 1. AGENTS.md vs handover план: `clickhouse-1c/ai/`
Первичный вывод был ошибочным. Директория `clickhouse-1c/ai/` существует и входит в разрешенный Python island. Противоречия нет.
### 2. Handover план vs код: `ru-patch-v5.js`
Handover (строка 185) проверяет URL `/js/ru-patch-v5.js` — это корректно после
деплоя через Ansible. Но handover упоминает файл так, будто он лежит в
`aw-server/`, тогда как в репозитории исходник называется `aw-ru-patch.js`,
а в `ru-patch-v5.js` переименовывается при деплое (Ansible task строка 450).
### 3. Handover план vs код: `grafana/` структура
Handover (секция 7) указывает `grafana/` для Grafana/Influx. В реальности:
- Основные дашборды лежат плоскими JSON в корне `grafana/` (нет provisioning-субдиректории)
- Отдельный стек `grafana-1c/` с собственным `docker-compose.yml` для MSSQL/Postgres 1C
- ClickHouse-1C имеет свой provisioning в `clickhouse-1c/grafana/provisioning/`
Handover-план не отражает это разделение.
### 4. Ansible: лишние playbook
В handover перечислены 5 playbook, но в `ansible/` существуют 17 файлов, включая:
- `deploy_grafana_dashboards.yml` (не упомянут)
- `deploy_file_1c_windows_telemetry.yml` (не упомянут)
- `deploy_file_1c_analytics.yml` (не упомянут)
- `deploy_dlp_evidence_sync.yml` (не упомянут)
- `deploy_dlp_full_stack.yml` (не упомянут)
- `deploy_aw_pfsense_poller.yml` (не упомянут)
- `audit_cryptopro_windows.yml` (не упомянут)
- `post_validate_aw_windows.yml` (не упомянут)
- `provision_proxmox_ct_and_deploy_aw.yml` (не упомянут)
- `provision_proxmox_ct_matrix_and_deploy_aw.yml` (не упомянут)
- `deploy_tsj_guardian_bot_proxmox.yml` (не упомянут)
- `install_full_stack.yml` (не упомянут)
Это не ошибка, но handover не полон.
### 5. DLP service файлы — в поддиректориях
Handover проверяет `systemctl status aw-dlp-policy-engine` и
`aw-dlp-case-management`, что корректно. Но `.service` файлы лежат не
напрямую в `aw-server/`, а в поддиректориях:
`aw-server/dlp-policy-engine/`, `aw-server/dlp-case-management/`,
`aw-server/dlp-compliance/`. Это не влияет на runtime.
---
## MISSING (некритично)
1. **`secrets/`** — не существует, вместо него `private-config/` с `.gitignore`
и `deploy.env.example`.
---
## Blocker (требует немедленного внимания)
### 🔴 CRITICAL: Production credentials в открытом виде
Файл **`ansible/inventory.ini`** игнорируется Git, но локально содержит production credentials в plaintext. Значения намеренно не приводятся в этом документе: audit-файлы нельзя превращать в копию секретов. Проверять только факт наличия `ansible_password`/host credentials и немедленно переносить их в vault или внешние переменные.
Это **реальные production credentials**:
- Production credentials из ignored inventory: Proxmox user password, AW server user password, Windows RDP administrator password. Значения не фиксировать в git, docs, logs или reports.
Это прямое нарушение AGENTS.md п. 4: "Never add real secrets from `secrets/`,
private `.env`, or host credentials."
**Рекомендация:** Немедленно заменить на переменные окружения или vault,
затем ротировать скомпрометированные пароли.
---
## Requires human approval
Следующие действия из handover-плана НЕЛЬЗЯ выполнять без подтверждения:
| Команда | Почему опасно |
|---------|---------------|
| `ansible-playbook -i inventory.ini deploy_aw_server.yml` | Реальный production деплой с живыми credentials |
| `ansible-playbook -i inventory.ini deploy_aw_windows.yml` | Может пересоздать Windows tasks, прервать сбор данных |
| `ansible-playbook -i inventory.ini deploy_detmir_portal.yml` | Перезапустит portal на production |
| `ansible-playbook -i inventory.ini deploy_grafana_check.yml` | Может изменить Grafana datasource |
| `systemctl restart aw-worktime-api` | Прервёт active reports |
| `systemctl start aw-worktime-influx-exporter.service` | Может записать дубли/битые данные в InfluxDB |
| `systemctl start aw-dlp-influx-exporter.service` | Аналогично |
| `cargo build --release --workspace` | Долгая компиляция (56 крейтов), может занять 20+ мин |
| `docker compose up -d` в `clickhouse-1c/` | Поднимет ClickHouse, может конфликтовать с существующим |
Все команды с прямым обращением к production (через inventory.ini или SSH)
требуют явного разрешения.
---
## Next actions
1. **Срочно:** убрать plaintext credentials из `ansible/inventory.ini`: перенести доступы в Ansible Vault или внешние переменные и ротировать уже раскрытые пароли.
2. **Сделано в текущем цикле:** AGENTS.md и handover-план дополнены правилом
sanitized audit, недостающими Ansible playbook и структурой `grafana/` vs
`grafana-1c/` vs `clickhouse-1c/grafana/`.
3. **Добавить `grafana/provisioning/`** структуру в корень для единого
подхода к дашбордам (сейчас JSON плоские — работает только через Ansible
копирование).
4. **Проверить ClickHouse .env** — если содержит реальные credentials,
добавить в .gitignore и вычистить из истории.