# План передачи проекта агенту 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://:5600/api/0/info curl -fsS http://: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_`; - `aw-watcher-window_`; - `aw-watcher-afk_` если AFK включен; - `aw-dlp-endpoint-signals_`; - `aw-file-operations_` если file ops включен. Развертывание: ```powershell .\windows\deploy-ensemble.ps1 ` -ServerHost ` -ServerPort 5600 ` -Domain ` -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://:5610/health | jq curl -fsS "http://:5610/reports/worktime/management?format=json&host=&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://:5601/health || true curl -fsS http://:5600/api/0/buckets/aw-dlp-endpoint-signals_ ``` ### 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://:5600/ | head curl -fsS http://:5600/js/ru-patch-v5.js | head curl -fsS http://: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://:8720/api/health | jq curl -fsS http://: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://: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://:5600/api/0/info curl -fsS http://:5610/health | jq ``` ### Шаг 5. Развернуть Windows/RDP ```bash ansible-playbook -i inventory.ini deploy_aw_windows.yml ``` Или вручную на Windows: ```powershell .\windows\deploy-ensemble.ps1 -ServerHost -ServerPort 5600 -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://:5610/reports/worktime/management?format=json&host=&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://:8720/api/health | jq curl -fsS http://: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_`. 2. Проверить `AW_WORKTIME_EVENTS_LIMIT`. 3. Проверить user normalization. 4. Проверить stale cache. 5. Не трогать ClickHouse. ### DLP пустой 1. Проверить Windows collector/guard. 2. Проверить `aw-dlp-endpoint-signals_`. 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; - написать короткий отчет без секретов. Если один из пунктов не выполнен, система не считается полностью переданной агенту.