Files
AWatch-rus/docs/OPENCODE_FULL_SYSTEM_HANDOVER_PLAN_RU.md
T

670 lines
25 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.
# План передачи проекта агенту OpenCode
Документ нужен агенту, который должен самостоятельно разворачивать и
сопровождать полный контур AWatch-rus. Писать и действовать нужно просто:
сначала понять слой, затем развернуть, затем проверить, затем зафиксировать
результат.
## 1. Цель
Развернуть AWatch-rus как единый контур:
- сбор активности пользователей с Windows/RDP рабочих мест;
- учет рабочего времени и RDP-сессий;
- DLP/ИБ-сигналы: clipboard, USB, print, browser domains, email, file ops;
- ActivityWatch Server и русифицированный WebUI;
- worktime API и управленческие отчеты;
- Grafana dashboards поверх InfluxDB;
- ClickHouse-контур для файловой 1С, расследований, detections и cases;
- портал руководителя/ИБ/эксплуатации;
- проверяемый deploy через Ansible, Rust-бинарники, systemd и Windows tasks.
Главное правило: система считается развернутой только когда есть свежие данные,
открываются интерфейсы, проходят health checks и есть понятный rollback.
Второе главное правило: agent может читать private/ignored файлы только для
проверки факта и типа секрета. Значения паролей, токенов, host credentials и
private URL нельзя переносить в markdown, audit, terminal summary, commit или
handoff. В отчете писать так: `ansible/inventory.ini содержит plaintext
credentials; значения не фиксировались; нужна ротация`.
## 2. Простая модель системы
Представь систему как цепочку:
```text
Windows/RDP users
-> Windows collectors / Rust agent
-> ActivityWatch API buckets
-> Rust services on AW server
-> Worktime reports + DLP services + Influx exporters
-> Grafana dashboards + Portal
-> ClickHouse/1C analytics where configured
```
Если ломается ранний слой, поздний слой тоже будет пустым. Нельзя начинать с
Grafana, если ActivityWatch buckets пустые. Нельзя чинить портал, если
`aw-worktime-api` degraded. Нельзя чинить ClickHouse для worktime, потому что
worktime reports не зависят от ClickHouse.
## 3. Роли пользователей
Система должна закрывать четыре роли.
1. Руководитель:
- видит, кто работал;
- видит активное время по дням;
- видит проблемные подразделения и риски;
- получает простой вывод без технического шума.
2. ИБ:
- видит DLP-инциденты;
- видит evidence и screenshot artifacts;
- видит DLP dashboards;
- может разбирать кейсы без прямого доступа к сырой базе.
3. Эксплуатация:
- видит свежесть buckets;
- видит состояние сервисов;
- видит failed units, timers, collector guard;
- может безопасно перезапустить нужный слой.
4. Аналитик 1С:
- видит аудит файловых баз 1С;
- видит detections, timeline, cases;
- видит состояние выгрузок и качество данных;
- понимает, где данные реальные, а где proxy/fallback.
## 4. Обязательный функционал
### 4.1 ActivityWatch core
Нужно:
- `activitywatch-server` работает и слушает `:5600`;
- WebUI открывается;
- CORS/landing page настроены;
- buckets создаются и обновляются;
- SQLite не перегружен тяжелыми запросами.
Проверки:
```bash
curl -fsS http://<AW_SERVER_HOST>:5600/api/0/info
curl -fsS http://<AW_SERVER_HOST>:5600/api/0/buckets | jq 'keys'
systemctl status activitywatch-server --no-pager
```
### 4.2 Windows/RDP сбор
Нужно:
- Windows toolkit установлен;
- есть `deployment-config.json`;
- есть scheduled tasks `ActivityWatch Launch [...]` и `ActivityWatch Recovery`;
- Rust collector guard работает, PowerShell fallback остается только как
fallback;
- `validate-deployment.ps1` возвращает `overallOk=True`;
- есть свежие buckets:
- `aw-worktime-sessions_<HOST>`;
- `aw-watcher-window_<HOST>`;
- `aw-watcher-afk_<HOST>` если AFK включен;
- `aw-dlp-endpoint-signals_<HOST>`;
- `aw-file-operations_<HOST>` если file ops включен.
Развертывание:
```powershell
.\windows\deploy-ensemble.ps1 `
-ServerHost <AW_SERVER_HOST> `
-ServerPort 5600 `
-Domain <WINDOWS_DOMAIN_OR_HOST> `
-Users user1,user2,user3
```
Проверки:
```powershell
.\windows\validate-deployment.ps1 | ConvertTo-Json -Depth 10
Get-ScheduledTask | Where-Object TaskName -like 'ActivityWatch*'
Get-Service AWatchRusCollectorGuard
```
### 4.3 Worktime reports
Нужно:
- `aw-worktime-api` работает на `:5610`;
- `/health` возвращает OK или понятный degraded;
- `/reports/worktime/management` строит HTML/JSON;
- report не считает служебные accounts и битые labels;
- stale cache включен для degraded path.
Проверки:
```bash
curl -fsS http://<AW_SERVER_HOST>:5610/health | jq
curl -fsS "http://<AW_SERVER_HOST>:5610/reports/worktime/management?format=json&host=<WINDOWS_HOSTNAME>&allow_stale=1" | jq '.status,.runtime'
systemctl status aw-worktime-api --no-pager
```
### 4.4 DLP
Нужно:
- DLP policy engine доступен;
- endpoint signals пишутся;
- incidents создаются;
- screenshots/evidence синхронизируются;
- case management и compliance работают, если включены;
- DLP health check зеленый или объясняет WARN/FAIL.
Проверки:
```bash
systemctl status aw-dlp-policy-engine aw-dlp-case-management --no-pager
curl -fsS http://<AW_SERVER_HOST>:5601/health || true
curl -fsS http://<AW_SERVER_HOST>:5600/api/0/buckets/aw-dlp-endpoint-signals_<HOST>
```
### 4.5 WebUI
Нужно:
- ActivityWatch WebUI не пустой;
- RU patch подключен;
- host sanitize script подключен;
- DLP review/rules UI доступен, если включен;
- worktime panel не ломает основной WebUI;
- browser cache не скрывает новую версию.
Развертывание:
```bash
ansible-playbook -i ansible/inventory.ini ansible/deploy_aw_server.yml
```
Проверки:
```bash
curl -fsS http://<AW_SERVER_HOST>:5600/ | head
curl -fsS http://<AW_SERVER_HOST>:5600/js/ru-patch-v5.js | head
curl -fsS http://<AW_SERVER_HOST>:5600/js/aw-host-sanitize.js | head
```
### 4.6 Portal
Нужно:
- портал работает как read-only рабочий кабинет;
- роли видят разные представления, но данные общие;
- `/api/health` показывает состояние источников;
- `/api/reports` возвращает KPI и markdown;
- portal не должен silently mutate AW/DLP/1C;
- внешняя публикация идет через gateway/auth, не через открытые raw ports.
Развертывание:
```bash
cd adk-rust
cargo build --release -p detmir-portal
cd ../ansible
ansible-playbook -i inventory.ini deploy_detmir_portal.yml
ansible-playbook -i inventory.ini deploy_proxmox_web_gateway.yml
```
Проверки:
```bash
curl -fsS http://<PORTAL_HOST>:8720/api/health | jq
curl -fsS http://<PORTAL_HOST>:8720/api/reports | jq '.status,.sources'
systemctl status detmir-portal --no-pager
```
## 5. Grafana + InfluxDB
### 5.1 Что должно быть
InfluxDB хранит агрегаты для Grafana:
- `aw_rdp_worktime_daily`;
- `aw_rdp_worktime_hourly`;
- `aw_rdp_worktime_summary_daily`;
- DLP measurements;
- health/self-test measurements.
Grafana должна показывать:
- главный AWatch-rus dashboard;
- RDP/user activity dashboard;
- DLP/security dashboard;
- DLP management dashboard;
- overview dashboard для владельца.
Структура в репозитории разделена на три разных контура:
- `grafana/` — плоские version-controlled JSON dashboards основного
AWatch-rus контура. Их импортирует `ansible/deploy_grafana_dashboards.yml`,
а проверяет `ansible/deploy_grafana_check.yml`.
- `grafana-1c/` — отдельный docker-compose стек для SQL-readable 1C
MSSQL/Postgres dashboards.
- `clickhouse-1c/grafana/provisioning/` — provisioning ClickHouse/file-1C
dashboards и datasource.
Не путать эти каталоги. Если меняется основной dashboard, править `grafana/*.json`
и прогонять dashboard deploy/check. Если меняется ClickHouse 1C dashboard,
смотреть `clickhouse-1c/grafana/provisioning/`.
### 5.2 Deploy order
1. Убедиться, что InfluxDB доступен.
2. Убедиться, что write tokens заданы в private inventory/env.
3. Развернуть AW server exporters.
4. Запустить exporters вручную один раз.
5. Проверить, что points записались.
6. Импортировать/provision Grafana dashboards.
7. Запустить `detmir-grafana-check`.
Команды:
```bash
systemctl start aw-worktime-influx-exporter.service
systemctl start aw-dlp-influx-exporter.service
journalctl -u aw-worktime-influx-exporter.service -n 50 --no-pager
journalctl -u aw-dlp-influx-exporter.service -n 50 --no-pager
cd ansible
ansible-playbook -i inventory.ini deploy_grafana_dashboards.yml
ansible-playbook -i inventory.ini deploy_grafana_check.yml
```
Проверки Grafana:
```bash
curl -u "$GRAFANA_USER:$GRAFANA_PASSWORD" \
http://<GRAFANA_HOST>:3000/api/datasources/uid/influxdb_aw/health
```
Ожидание: datasource OK, dashboards открываются, panels не пустые, labels
пользователей нормализованы.
### 5.3 Правила для dashboard
- Не править только руками в Grafana UI; сначала править JSON/provisioning в
репозитории.
- Для worktime не показывать machine accounts, битые Unicode labels и дубли
регистра.
- Owner-facing aggregate должен называться понятным языком, например
`Все сотрудники`, а не техническим словом `Команда`.
- После импорта проверить dashboard API и открыть страницу через gateway.
## 6. ClickHouse + файловая 1С
### 6.1 Назначение
Этот контур нужен, когда 1С файловая и нужен не только KPI, а audit stack:
```text
1C exports / reglog / host telemetry
-> landing/*
-> aw-1c-ingest-rust
-> ClickHouse analytics_1c
-> detections / timeline / cases / company intelligence
-> Grafana + Portal + briefs
```
### 6.2 Что развернуть
- ClickHouse;
- Grafana datasource ClickHouse;
- schema из `clickhouse-1c/clickhouse/init/*.sql`;
- landing каталоги;
- ingest timer/service;
- detections SQL;
- company intelligence refresh;
- read-only 1C analytics API;
- dashboards из `clickhouse-1c/grafana/provisioning/dashboards/files/`.
### 6.3 Minimal local bootstrap
```bash
cd clickhouse-1c
cp .env.example .env
docker compose up -d
mkdir -p landing/{documents,postings,business_events,document_changes,companies,reglog,audit,host}
cp etl/config.example.yml etl/config.yml
```
### 6.4 Production ingest
```bash
cd adk-rust
cargo build --release -p aw-1c-ingest
/usr/local/bin/aw-1c-ingest-rust --root /opt/activitywatch/clickhouse-1c
clickhouse-client --queries-file /opt/activitywatch/clickhouse-1c/detections/insert_detections.sql
clickhouse-client --queries-file /opt/activitywatch/clickhouse-1c/detections/build_entity_timeline.sql
```
### 6.5 Проверки ClickHouse/1С
```bash
clickhouse-client --query "SHOW DATABASES"
clickhouse-client --database analytics_1c --query "SHOW TABLES"
clickhouse-client --database analytics_1c --query "SELECT count() FROM business_events"
clickhouse-client --database analytics_1c --query "SELECT count() FROM detections"
```
Ожидание:
- таблицы существуют;
- raw/normalized слои не пустые, если есть выгрузки;
- detections считаются;
- Grafana 1C dashboards открываются;
- API компании/brief отвечает read-only.
## 7. Модули и ответственность
| Слой | Где смотреть | За что отвечает |
| --- | --- | --- |
| Rust runtime | `adk-rust/crates/*` | production binaries, checks, exporters, portal, ingest |
| AW server | `aw-server/`, `ansible/deploy_aw_server.yml` | ActivityWatch, WebUI, worktime, DLP services |
| Windows | `windows/`, `ansible/deploy_aw_windows.yml` | collectors, tasks, guard, validation |
| Grafana/Influx | `grafana/`, `ansible/deploy_grafana_dashboards.yml`, `ansible/deploy_grafana_check.yml` | flat dashboard JSON import, datasource/freshness checks |
| SQL 1C Grafana | `grafana-1c/` | separate MSSQL/Postgres 1C Grafana stack |
| 1C/ClickHouse | `clickhouse-1c/`, `clickhouse-1c/ai/`, `clickhouse-1c/grafana/provisioning/` | file 1C analytics, detections, cases, allowed Python AI helpers |
| Portal | `adk-rust/crates/detmir-portal`, `docs/PORTAL_RU.md` | role views, reports, health |
| Gateway | `ansible/deploy_proxmox_web_gateway.yml` | external protected routes |
| Docs/runbooks | `docs/`, `adk-rust/RUNBOOK.md` | operating procedures |
### 7.1 Ansible playbook map
Перед deploy агент должен понимать назначение playbook, а не запускать их
пакетом.
| Playbook | Назначение |
| --- | --- |
| `deploy_aw_server.yml` | ActivityWatch server, WebUI, worktime/DLP server side |
| `deploy_aw_windows.yml` | Windows/RDP collectors and validation artifacts |
| `post_validate_aw_windows.yml` | post-deploy Windows validation |
| `deploy_detmir_portal.yml` | portal service |
| `deploy_proxmox_web_gateway.yml` | protected gateway routes |
| `deploy_grafana_dashboards.yml` | import flat `grafana/*.json` dashboards |
| `deploy_grafana_check.yml` | datasource/dashboard health checks |
| `deploy_file_1c_windows_telemetry.yml` | file-1C Windows telemetry |
| `deploy_file_1c_analytics.yml` | file-1C analytics layer |
| `deploy_dlp_evidence_sync.yml` | DLP evidence artifact sync |
| `deploy_dlp_full_stack.yml` | full DLP server-side stack |
| `deploy_aw_pfsense_poller.yml` | pfSense poller integration |
| `audit_cryptopro_windows.yml` | Windows CryptoPro audit |
| `provision_proxmox_ct_and_deploy_aw.yml` | provision one Proxmox CT and deploy AW |
| `provision_proxmox_ct_matrix_and_deploy_aw.yml` | provision CT matrix and deploy AW |
| `deploy_tsj_guardian_bot_proxmox.yml` | Proxmox guardian bot |
| `install_full_stack.yml` | broad full-stack install wrapper; use only with explicit scope |
## 8. Полный порядок развёртывания
### Шаг 0. Не ломать рабочий контур
Перед любыми изменениями:
```bash
git status --short --branch
git log --oneline -5
```
Если есть unrelated dirty tree, не откатывать его. Работать только с нужными
файлами.
### Шаг 1. Подготовить private конфигурацию
Проверить:
- `ansible/inventory.ini`;
- private group vars;
- Influx tokens;
- Grafana credentials;
- Windows host/user list;
- gateway host/auth;
- ClickHouse credentials;
- 1C export paths.
Нельзя коммитить реальные secrets. Нельзя вставлять значения из
`ansible/inventory.ini`, private env, vault, runtime configs или host credentials
в docs/audit. Разрешено писать только факт: где найдено, какой тип секрета, что
сделать для remediation.
### Шаг 2. Собрать Rust
```bash
cd adk-rust
cargo fmt --all -- --check
cargo build --release --workspace
cargo test -p detmir-core
cargo test -p detmir-portal
cargo test -p worktime-api
cargo test -p worktime-influx-exporter
```
Если workspace слишком большой, собирать targeted crates, которые нужны
текущему deploy.
### Шаг 3. Проверить Ansible syntax
```bash
cd ansible
ansible-playbook --syntax-check deploy_aw_server.yml
ansible-playbook --syntax-check deploy_aw_windows.yml
ansible-playbook --syntax-check deploy_detmir_portal.yml
ansible-playbook --syntax-check deploy_grafana_dashboards.yml
ansible-playbook --syntax-check deploy_grafana_check.yml
```
### Шаг 4. Развернуть AW server
```bash
ansible-playbook -i inventory.ini deploy_aw_server.yml
```
После:
```bash
systemctl --failed --no-pager
systemctl status activitywatch-server aw-worktime-api --no-pager
curl -fsS http://<AW_SERVER_HOST>:5600/api/0/info
curl -fsS http://<AW_SERVER_HOST>:5610/health | jq
```
### Шаг 5. Развернуть Windows/RDP
```bash
ansible-playbook -i inventory.ini deploy_aw_windows.yml
```
Или вручную на Windows:
```powershell
.\windows\deploy-ensemble.ps1 -ServerHost <AW_SERVER_HOST> -ServerPort 5600 -Domain <DOMAIN> -Users user1,user2
.\windows\validate-deployment.ps1
```
После проверить свежесть buckets на AW server.
### Шаг 6. Запустить worktime chain
```bash
systemctl restart aw-worktime-api
systemctl start aw-worktime-prewarm.service || true
curl -fsS "http://<AW_SERVER_HOST>:5610/reports/worktime/management?format=json&host=<WINDOWS_HOSTNAME>&allow_stale=1" | jq
```
### Шаг 7. Запустить Influx exporters
```bash
systemctl start aw-worktime-influx-exporter.service
systemctl start aw-dlp-influx-exporter.service
journalctl -u aw-worktime-influx-exporter.service -n 50 --no-pager
journalctl -u aw-dlp-influx-exporter.service -n 50 --no-pager
```
Ожидание: `wrote ... points`.
### Шаг 8. Развернуть Grafana dashboards/checks
```bash
ansible-playbook -i inventory.ini deploy_grafana_dashboards.yml
ansible-playbook -i inventory.ini deploy_grafana_check.yml
```
Проверить:
- datasource health OK;
- dashboard pages HTTP 200;
- worktime panels не пустые;
- DLP panels не пустые при наличии DLP events.
### Шаг 9. Развернуть 1C/ClickHouse
Если 1С контур нужен:
```bash
cd clickhouse-1c
docker compose up -d
clickhouse-client --queries-file clickhouse/init/00_database.sql
clickhouse-client --queries-file clickhouse/init/01_raw_tables.sql
clickhouse-client --queries-file clickhouse/init/02_core_tables.sql
clickhouse-client --queries-file clickhouse/init/03_views.sql
clickhouse-client --queries-file clickhouse/init/04_company_intelligence.sql
clickhouse-client --queries-file clickhouse/init/05_financial_reporting.sql
```
Затем включить ingest, detections и dashboards.
### Шаг 10. Развернуть portal/gateway
```bash
cd adk-rust
cargo build --release -p detmir-portal
cd ../ansible
ansible-playbook -i inventory.ini deploy_detmir_portal.yml
ansible-playbook -i inventory.ini deploy_proxmox_web_gateway.yml
```
Проверить:
```bash
curl -fsS http://<PORTAL_HOST>:8720/api/health | jq
curl -fsS http://<PORTAL_HOST>:8720/api/reports | jq '.status,.sources'
```
### Шаг 11. Финальная приемка
Минимум:
- `systemctl --failed` пустой на ключевых узлах;
- AW API отвечает;
- buckets свежие;
- Windows validation OK;
- worktime report OK;
- DLP health OK/WARN с понятной причиной;
- Influx exporters пишут points;
- Grafana datasource OK;
- dashboards открываются;
- portal health OK;
- ClickHouse/1C tables не пустые, если включен 1C контур;
- нет secrets в staged diff.
## 9. Диагностика по симптомам
### Portal пустой
1. Проверить `/portal/api/health`.
2. Проверить `aw-worktime-api`.
3. Проверить ActivityWatch buckets.
4. Проверить ClickHouse только если пустой именно 1C/security-events слой.
### Grafana пустая
1. Проверить Influx datasource health.
2. Проверить exporters logs.
3. Проверить Influx bucket/measurements.
4. Проверить dashboard JSON/provisioning.
5. Проверить time range и host variable.
### Worktime неверный
1. Проверить `aw-worktime-sessions_<HOST>`.
2. Проверить `AW_WORKTIME_EVENTS_LIMIT`.
3. Проверить user normalization.
4. Проверить stale cache.
5. Не трогать ClickHouse.
### DLP пустой
1. Проверить Windows collector/guard.
2. Проверить `aw-dlp-endpoint-signals_<HOST>`.
3. Проверить policy engine.
4. Проверить DLP case/evidence services.
5. Проверить DLP Influx exporter только для Grafana.
### 1C пустая
1. Проверить landing files.
2. Проверить `aw-1c-ingest-rust`.
3. Проверить ClickHouse schema.
4. Проверить detections SQL.
5. Проверить Grafana ClickHouse datasource.
## 10. Как агент должен работать
1. Сначала читать `AGENTS.md`.
2. Затем читать этот документ.
3. Для конкретного слоя читать профильный doc:
- Windows: `docs/windows/deployment.md`;
- Worktime: `docs/OPERATIONS_RUNBOOK_WORKTIME_RU.md`;
- Portal: `docs/PORTAL_RU.md`;
- Grafana: `docs/GRAFANA_DASHBOARDS_RU.md`;
- 1C/ClickHouse: `clickhouse-1c/README.md`;
- Rust migration/runtime: `adk-rust/RUNBOOK.md`.
4. Перед изменением фиксировать `git status`.
5. Перед deploy делать syntax/build checks.
6. После deploy делать runtime checks.
7. Перед созданием docs/audit по private files проверять, что в текст не попали
значения credentials. Писать только sanitized факт и remediation.
8. В ответе пользователю писать:
- что изменено;
- какие команды выполнены;
- что проверено;
- что осталось рискованным или не проверено.
## 11. Запреты
- Не печатать secrets.
- Не копировать значения secrets из private/ignored файлов в audit, markdown,
terminal summary, commit message или handoff.
- Не коммитить private inventory/env.
- Не править production Grafana только руками без отражения в repo.
- Не перезапускать все сервисы подряд.
- Не трогать сетевой периметр/gateway/pfSense без отдельной команды.
- Не делать destructive DB operations без backup.
- Не считать `ansible --syntax-check` полной проверкой: нужна runtime проверка.
- Не считать открывшийся UI доказательством: нужны свежие данные.
## 12. Итоговая Definition of Done
Полная замена ручного оператора возможна только если агент умеет:
- поднять server и Windows collectors;
- проверить buckets и freshness;
- восстановить worktime report;
- запустить Influx exporters;
- импортировать/проверить Grafana dashboards;
- поднять ClickHouse/1C ingest;
- проверить portal health/reports;
- найти слой отказа по симптомам;
- сделать rollback по backup;
- написать короткий отчет без секретов.
Если один из пунктов не выполнен, система не считается полностью переданной
агенту.