617 lines
28 KiB
Markdown
617 lines
28 KiB
Markdown
# Roadmap: замена PowerShell на Rust EXE
|
||
|
||
Дата: 2026-06-05
|
||
|
||
Цель: убрать зависимость AWatch-rus от PowerShell-скриптов на рабочих
|
||
хостах и заменить их на самодостаточные Rust EXE/службы без потери данных,
|
||
без ухудшения пилотной демонстрации и без изменения функционального объема.
|
||
|
||
Документ описывает порядок миграции. Он не вводит новые функции: каждая Rust
|
||
замена сначала должна повторить текущий контракт PowerShell-компонента.
|
||
|
||
Операторский checkpoint от 2026-06-05 сохранен в private `.ops`-контуре:
|
||
Phase 0 live inventory выполнен, Phase 2 validation для уже переведенных
|
||
Windows Rust paths выполнен успешно. В tracked документации не публикуются live
|
||
hostnames, private IP, токены и runtime evidence paths.
|
||
|
||
## 1. Целевое состояние
|
||
|
||
К концу миграции:
|
||
|
||
- на Windows/RDP-хостах регулярный сбор данных, evidence-sync, 1C upload,
|
||
guard/recovery и validation выполняются Rust EXE;
|
||
- в Scheduled Tasks и Windows Services нет штатных AWatch-rus задач, которые
|
||
запускают `powershell.exe` или `pwsh.exe`;
|
||
- install-kit поставляет Rust EXE, конфиги и service/task definitions вместо
|
||
runtime `.ps1`;
|
||
- Ansible разворачивает Rust binaries и конфиги, а не копирует PowerShell
|
||
runtime scripts;
|
||
- Telegram/Codex/bot контур вызывает Rust helpers или читает Rust JSON
|
||
snapshots, не опираясь на пути к `.ps1`;
|
||
- legacy PowerShell хранится только как временный rollback-слой до прохождения
|
||
acceptance gates и затем удаляется из install-kit;
|
||
- Linux/AW/Proxmox части остаются Rust-first; Ansible может остаться
|
||
оркестратором, потому что это инфраструктурный deploy layer, а не runtime
|
||
PowerShell.
|
||
|
||
## 2. Текущее состояние
|
||
|
||
Уже выполнено или частично выполнено:
|
||
|
||
- `awatch-agent-rs` заменяет Windows `worktime-session-collector.ps1` для
|
||
worktime/RDP path. Legacy PowerShell оставлен как fallback и управляется
|
||
`collectors.worktimeSessionEnabled`, `worktimeSessionMode`,
|
||
`worktimeLegacyFallbackEnabled`.
|
||
- `aw-windows-telemetry.exe` уже используется для:
|
||
- `file1c-upload`;
|
||
- `dlp-evidence-sync`.
|
||
- `aw-1c-ingest-rust` пишет 1C/file analytics в ClickHouse на серверной
|
||
стороне.
|
||
- `aw-windows-telemetry.exe validate-deployment` добавлен как Rust validation
|
||
gate первого уровня. Он проверяет уже мигрированные Windows Rust paths,
|
||
свежесть worktime bucket, Rust collector guard service и queue sanity без
|
||
запуска PowerShell.
|
||
- `AWatchRusCollectorGuard` переключен с `aw-collector-guard.ps1` на
|
||
`aw-windows-telemetry.exe collector-guard`. Старый PowerShell guard оставлен
|
||
как rollback script, но штатный service runtime его не запускает. Rust guard
|
||
получает `sessionId` из native process snapshot, дедуплицирует legacy
|
||
collectors по `(kind, sessionId)` и не запускает пользовательские launch
|
||
tasks повторно, если legacy collectors уже активны.
|
||
- `aw-windows-telemetry.exe` добавил P0 runtime collector subcommands:
|
||
`browser-domains-collector`, `dlp-endpoint-collector`,
|
||
`file-operations-collector`. На live Windows/RDP host они включены через
|
||
`collectors.*Mode=rust_primary`, работают в трех пользовательских сессиях,
|
||
а P0 PowerShell collector runtime отсутствует. Это не означает полного
|
||
удаления legacy `.ps1`: они оставлены как rollback/reference до расширения
|
||
глубокой функциональной parity.
|
||
- Основные серверные AWatch-rus/AW/DLP helpers уже Rust-first:
|
||
`detmir-status`, `detmir-check`, `detmir-auto`, `detmir-heal-safe`,
|
||
`aw-rus-healthd-rust`, `dlp-*`, `worktime-*`, `aw-health-check`,
|
||
`check-aw-data`, `aw-prune-local-state` и другие.
|
||
|
||
Остаток PowerShell в рабочем дереве:
|
||
|
||
- 26 product `.ps1` в `windows/`;
|
||
- operator/MCP helper `scripts/powershell/detmir-powershell-profile.ps1`;
|
||
- parse-check helper `.pssa_run.ps1`;
|
||
- `.venv/bin/activate.ps1` внутри virtualenv не является продуктовым
|
||
компонентом и не входит в миграцию.
|
||
|
||
## 3. Инвентаризация Windows PowerShell
|
||
|
||
| Скрипт | Роль | Цель миграции | Приоритет |
|
||
|---|---|---|---|
|
||
| `worktime-session-collector.ps1` | RDP/worktime сбор | закрепить замену через `awatch-agent-rs`, затем удалить fallback | P0 done/stabilize |
|
||
| `browser-domains-native-collector.ps1` | browser/domain и DLP web-сигналы | `aw-windows-telemetry.exe browser-domains-collector`; live Rust primary, legacy fallback/reference | P0 live/stabilize |
|
||
| `dlp-endpoint-signals-collector.ps1` | clipboard/USB/print/DLP incident signals | `aw-windows-telemetry.exe dlp-endpoint-collector`; live Rust primary, screenshots только для DLP events | P0 live/stabilize |
|
||
| `file-operations-collector.ps1` | file create/delete/rename/archive hints | `aw-windows-telemetry.exe file-operations-collector`; live Rust primary with queue/spool | P0 live/stabilize |
|
||
| `email-outbound-collector.ps1` | outbound email metadata/DLP | Rust email metadata collector | P1 |
|
||
| `dlp-policy-client.ps1` | получение DLP policy | Rust policy client/cache | P1 |
|
||
| `export-upload-file-1c-telemetry.ps1` | 1C telemetry upload | закрепить `aw-windows-telemetry.exe file1c-upload`, затем удалить legacy | P0 done/stabilize |
|
||
| `sync-dlp-evidence-artifacts.ps1` | DLP evidence upload | закрепить `aw-windows-telemetry.exe dlp-evidence-sync` | P0 done/stabilize |
|
||
| `export-evtx-for-hayabusa.ps1` | bounded EVTX export | Rust EVTX export helper | P1 |
|
||
| `export-upload-hayabusa-to-aw-server.ps1` | EVTX/Hayabusa upload | Rust upload helper или режим в `aw-windows-telemetry.exe` | P1 |
|
||
| `aw-standalone-service.ps1` | supervisor service wrapper | Rust Windows service wrapper | P0 |
|
||
| `aw-collector-guard.ps1` | guard/restart/recovery | Rust guard with allowlist, lock, cooldown | P0 done/stabilize |
|
||
| `hardening-recovery.ps1` | recovery/hardening | Rust recovery CLI; destructive actions behind `--apply` | P1 |
|
||
| `validate-deployment.ps1` | post-deploy validation | Rust validation CLI `aw-windows-telemetry.exe validate-deployment`; расширять до полной parity перед удалением `.ps1` | P0 started |
|
||
| `rebuild-worktime-tasks.ps1` | rebuild scheduled tasks | Rust task reconciliation CLI | P1 |
|
||
| `fix-session-watchers.ps1` | repair session watchers | Rust repair subcommand | P2 |
|
||
| `cleanup-disc-sessions.ps1` | cleanup stale disconnected sessions | Rust maintenance subcommand | P2 |
|
||
| `migrate-awatch-rus-paths.ps1` | path migration | Rust migration CLI with backup and dry-run | P1 |
|
||
| `deploy-single-user.ps1` | single-user deploy | Rust/Ansible-backed installer action | P1 |
|
||
| `deploy-domain-users.ps1` | domain deploy | Rust/Ansible-backed installer action | P1 |
|
||
| `deploy-ensemble.ps1` | orchestrated deploy | Rust deploy coordinator or Ansible playbook wrapper | P1 |
|
||
| `install-standalone-service.ps1` | local service install | Rust installer/bootstrap CLI | P0 |
|
||
| `install-collector-guard-service.ps1` | guard service install | Rust installer/bootstrap CLI | P0 |
|
||
| `install-dlp-client.ps1` | DLP client install | Rust installer/bootstrap CLI | P1 |
|
||
| `audit-cryptopro.ps1` | CryptoPro audit | Rust audit CLI | P2 |
|
||
| `run-user1-probe.ps1` | manual probe | Rust diagnostic probe | P2 |
|
||
|
||
## 4. Неприкосновенные ограничения
|
||
|
||
- Не делать big-bang replacement.
|
||
- Не отключать PowerShell fallback до прохождения shadow/parity gates.
|
||
- Не переносить функции, которые требуют скрытого сбора, keylogging, screen
|
||
recording или content interception. Скриншоты допустимы только для DLP
|
||
incident evidence, если это явно включено политикой.
|
||
- Не менять бизнес-логику DLP, 1C, worktime или evidence при переносе.
|
||
- Не менять thresholds, bucket names, event schema и ClickHouse schema без
|
||
отдельного решения.
|
||
- Не ломать install-kit и rollback ради удаления `.ps1`.
|
||
- Не хранить live hostnames, private IP, tokens, passwords или runtime evidence
|
||
paths в публичных tracked docs.
|
||
|
||
## 5. Общий контракт каждого Rust EXE
|
||
|
||
Каждый заменяющий EXE должен иметь:
|
||
|
||
- `--config <path>`;
|
||
- `--json` для машинного вывода;
|
||
- `--dry-run` для всех действий, меняющих состояние;
|
||
- `--timeout-seconds`;
|
||
- `--log-path` или structured logging в штатный каталог;
|
||
- `--version`;
|
||
- стабильные exit codes:
|
||
- `0` - OK;
|
||
- `1` - usage/config/runtime error;
|
||
- `2` - check выполнен, но состояние WARN/FAIL;
|
||
- `3` - action запрещен safety policy;
|
||
- structured JSON event для audit trail;
|
||
- lock/cooldown для guard/recovery/actions;
|
||
- spool/queue для сетевых upload path;
|
||
- atomic writes для state files;
|
||
- no implicit sudo/admin: повышенные права должны быть видны в task/service
|
||
definition;
|
||
- rollback compatibility с текущими config keys.
|
||
|
||
## 6. Фазы миграции
|
||
|
||
### Phase 0. Baseline и реестр вызовов
|
||
|
||
Цель: зафиксировать, где PowerShell реально используется.
|
||
|
||
Действия:
|
||
|
||
1. Сканировать репозиторий:
|
||
- `windows/*.ps1`;
|
||
- `windows/installkit/innosetup/*.iss`;
|
||
- `ansible/*.yml`;
|
||
- `ansible/group_vars/*.yml`;
|
||
- `scripts/*`;
|
||
- docs/runbooks.
|
||
2. Снять runtime baseline на тестовом Windows host:
|
||
- Scheduled Tasks;
|
||
- Windows Services;
|
||
- текущие command lines процессов;
|
||
- `deployment-config.json`;
|
||
- свежесть AW buckets;
|
||
- наличие DLP evidence и 1C upload.
|
||
3. Для каждого скрипта зафиксировать:
|
||
- входные параметры;
|
||
- env/config keys;
|
||
- side effects;
|
||
- event schema;
|
||
- log/state paths;
|
||
- expected exit codes;
|
||
- rollback path.
|
||
|
||
Выход фазы:
|
||
|
||
- `docs/POWERSHELL_TO_RUST_ROADMAP_RU.md` как базовая дорожная карта;
|
||
- отдельный runtime inventory для live-контура в private/operator notes, без
|
||
публикации секретов.
|
||
|
||
### Phase 1. Windows Rust foundation
|
||
|
||
Цель: подготовить общий Windows runtime вместо набора разрозненных EXE.
|
||
|
||
Действия:
|
||
|
||
1. Расширить существующие `awatch-agent-rs` и `aw-windows-telemetry` только в
|
||
рамках parity, без новых функций.
|
||
2. Вынести общие Windows helpers:
|
||
- config loading;
|
||
- ActivityWatch HTTP client;
|
||
- evidence upload client;
|
||
- Windows task/service inspection;
|
||
- Event Log/EVTX access;
|
||
- filesystem state/spool;
|
||
- structured logs/audit.
|
||
3. Зафиксировать единый Windows config contract:
|
||
- `C:\ProgramData\AWatch-rus\deployment-config.json`;
|
||
- `C:\Program Files\AWatch-rus\windows\*.exe`;
|
||
- `C:\ProgramData\AWatch-rus\logs`;
|
||
- `C:\ProgramData\AWatch-rus\spool`;
|
||
- `C:\ProgramData\AWatch-rus\switch-backups`.
|
||
|
||
Gate:
|
||
|
||
```bash
|
||
cd adk-rust
|
||
cargo fmt --all -- --check
|
||
cargo test --workspace
|
||
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||
cargo build --release -p awatch-agent-rs -p aw-windows-telemetry
|
||
```
|
||
|
||
### Phase 2. Закрепить уже выполненные замены
|
||
|
||
Цель: не переписать повторно то, что уже переведено, а довести до production
|
||
definition of done.
|
||
|
||
Компоненты:
|
||
|
||
- `worktime-session-collector.ps1` -> `awatch-agent-rs`;
|
||
- `export-upload-file-1c-telemetry.ps1` -> `aw-windows-telemetry.exe file1c-upload`;
|
||
- `sync-dlp-evidence-artifacts.ps1` -> `aw-windows-telemetry.exe dlp-evidence-sync`;
|
||
- `aw-collector-guard.ps1` -> `aw-windows-telemetry.exe collector-guard`
|
||
через `AWatchRusCollectorGuard` service wrapper;
|
||
- серверный writer -> `aw-1c-ingest-rust`.
|
||
|
||
Действия:
|
||
|
||
1. Проверить, что task/service actions запускают EXE, а не PowerShell.
|
||
2. Проверить, что PowerShell fallback выключен там, где Rust уже стабилен.
|
||
3. Проверить свежесть buckets/ClickHouse/evidence after restart.
|
||
4. Обновить install-kit file list: Rust EXE являются primary artifact.
|
||
5. Оставить legacy `.ps1` только как rollback на ограниченный период.
|
||
|
||
Gate:
|
||
|
||
- `ActivityWatch File1C Upload` запускает `aw-windows-telemetry.exe`;
|
||
- `ActivityWatch DLP Evidence Sync` запускает `aw-windows-telemetry.exe`;
|
||
- worktime events имеют `source=awatch-agent-rs`;
|
||
- `AWatchRusCollectorGuard` запущен и его child process -
|
||
`aw-windows-telemetry.exe collector-guard`;
|
||
- guard не создает duplicate legacy browser/fileops/DLP endpoint collectors
|
||
при stale bucket: при уже активных collectors launch tasks не запускаются
|
||
повторно;
|
||
- 1C ClickHouse ingest идет по `aw-1c-ingest-rust`;
|
||
- PowerShell worktime process count = 0 в штатном режиме.
|
||
- PowerShell `aw-collector-guard.ps1` process count = 0 в штатном режиме.
|
||
|
||
### Phase 3. Runtime collectors
|
||
|
||
Цель: заменить регулярный сбор данных на Windows.
|
||
|
||
Порядок:
|
||
|
||
1. `browser-domains-native-collector.ps1`
|
||
- current status: live Rust primary through
|
||
`aw-windows-telemetry.exe browser-domains-collector`;
|
||
- ActivityWatch window/category health events are written with
|
||
`source=aw-windows-telemetry-rust`;
|
||
- UIAutomation URL/domain extraction implemented in Rust: browser process
|
||
detection, normalized URL, host/rootDomain, default/custom category rules,
|
||
`aw-watcher-web-*`, `aw-detmir-web-category_*` and web DLP incident
|
||
schema preserve the legacy bucket/event contract;
|
||
- live disconnected RDP sessions may legitimately report
|
||
`browserDetected=false` and `urlDetected=false` until a browser is
|
||
foreground in an interactive user session;
|
||
- screenshots только для DLP incident evidence.
|
||
2. `dlp-endpoint-signals-collector.ps1`
|
||
- current status: live Rust primary through
|
||
`aw-windows-telemetry.exe dlp-endpoint-collector`;
|
||
- endpoint collector health is written with
|
||
`source=aw-windows-telemetry-rust`;
|
||
- clipboard metadata/hash/length, USB insert, print job metadata and DLP
|
||
incident event semantics implemented in Rust with legacy fields:
|
||
`requestedAction`, `enforcementMode`, `nativeChannelAction`,
|
||
`enforcementSuppressed`, content pack matches and `enforced`;
|
||
- destructive endpoint enforcement for USB write-block and print cancel is
|
||
intentionally not enabled during pilot hardening: Rust emits equivalent
|
||
audit/incident semantics and suppresses unsafe block actions unless a
|
||
separate enforcement decision is made;
|
||
- incident screenshot policy remains: screenshots only for DLP events.
|
||
3. `file-operations-collector.ps1`
|
||
- current status: live Rust primary through
|
||
`aw-windows-telemetry.exe file-operations-collector`;
|
||
- bounded filesystem watcher, operation schema, queue/spool and
|
||
create/rename/delete smoke are verified;
|
||
- per-session queue/state/log files are used, so RDP sessions do not share
|
||
one state file;
|
||
- legacy PowerShell remains installed only as rollback/reference.
|
||
4. `email-outbound-collector.ps1`
|
||
- metadata-only parity;
|
||
- Outlook/SMTP mode behavior preserved;
|
||
- no content interception beyond current documented behavior.
|
||
5. `dlp-policy-client.ps1`
|
||
- Rust policy fetch/cache;
|
||
- strict validation;
|
||
- safe fallback to last known good policy.
|
||
|
||
Shadow-mode:
|
||
|
||
- Rust collector writes `source=<rust-component>` and `mode=shadow`;
|
||
- PowerShell remains primary during comparison;
|
||
- compare event counts, schema, timestamps, severity, policy hits and evidence
|
||
links for at least several collection cycles.
|
||
|
||
Gate:
|
||
|
||
- no duplicate management conclusions in portal;
|
||
- event schema compatible with current AW/DLP consumers;
|
||
- no stale buckets introduced;
|
||
- no uncontrolled screenshot capture;
|
||
- Rust collector survives AW API outage by spooling and later flushing.
|
||
|
||
### Phase 4. Guard, service wrapper и recovery
|
||
|
||
Цель: заменить PowerShell, который управляет процессами и восстановлением.
|
||
|
||
Компоненты:
|
||
|
||
- `aw-standalone-service.ps1`;
|
||
- `aw-collector-guard.ps1`;
|
||
- `hardening-recovery.ps1`;
|
||
- `rebuild-worktime-tasks.ps1`;
|
||
- `fix-session-watchers.ps1`;
|
||
- `cleanup-disc-sessions.ps1`.
|
||
|
||
Действия:
|
||
|
||
1. Сделать Rust Windows service wrapper:
|
||
- supervises configured collectors;
|
||
- records child process state;
|
||
- no hidden PowerShell spawn in normal mode.
|
||
2. Сделать Rust guard/recovery:
|
||
- allowlist actions only;
|
||
- lock file;
|
||
- cooldown;
|
||
- dry-run by default for destructive or repair actions;
|
||
- audit entry for every change.
|
||
3. Перевести rebuild/fix/cleanup в subcommands одного maintenance EXE.
|
||
|
||
Gate:
|
||
|
||
- controlled restart of one collector works;
|
||
- stale collector detection matches old guard;
|
||
- recovery cannot restart arbitrary process/service;
|
||
- rollback restores PowerShell guard/service within one operator action.
|
||
|
||
### Phase 5. Install/deploy/validate
|
||
|
||
Цель: install-kit перестает запускать PowerShell как штатный bootstrap.
|
||
|
||
Компоненты:
|
||
|
||
- `install-standalone-service.ps1`;
|
||
- `install-collector-guard-service.ps1`;
|
||
- `install-dlp-client.ps1`;
|
||
- `deploy-single-user.ps1`;
|
||
- `deploy-domain-users.ps1`;
|
||
- `deploy-ensemble.ps1`;
|
||
- `validate-deployment.ps1`;
|
||
- `migrate-awatch-rus-paths.ps1`;
|
||
- InnoSetup `AWatch-rus-InnoSetup.iss`;
|
||
- Ansible Windows playbooks/group vars.
|
||
|
||
Действия:
|
||
|
||
1. Создать Rust bootstrap/installer EXE:
|
||
- install/update service;
|
||
- install/update scheduled tasks;
|
||
- write config atomically;
|
||
- backup previous config/tasks;
|
||
- emit JSON validation report.
|
||
2. Перевести validation в Rust:
|
||
- task actions;
|
||
- service status;
|
||
- bucket freshness;
|
||
- file permissions;
|
||
- rust binary version matrix;
|
||
- no PowerShell runtime task check.
|
||
3. Обновить InnoSetup:
|
||
- package `*.exe`;
|
||
- run Rust bootstrap;
|
||
- keep `.ps1` out of normal install payload after stabilization.
|
||
4. Обновить Ansible:
|
||
- deploy EXE;
|
||
- configure task/service actions to EXE;
|
||
- remove default `.ps1` paths from bot/env after migration.
|
||
|
||
Gate:
|
||
|
||
- clean install on test Windows host;
|
||
- upgrade from PowerShell install to Rust install;
|
||
- rollback to previous package;
|
||
- `validate-deployment` JSON is consumed by CI/operator without parsing human
|
||
text;
|
||
- install-kit verification confirms no `powershell.exe` in primary install
|
||
action.
|
||
|
||
### Phase 6. Ops-only хвост
|
||
|
||
Цель: убрать одноразовые PowerShell helpers.
|
||
|
||
Компоненты:
|
||
|
||
- `audit-cryptopro.ps1`;
|
||
- `run-user1-probe.ps1`;
|
||
- `scripts/powershell/detmir-powershell-profile.ps1`;
|
||
- `.pssa_run.ps1`.
|
||
|
||
Решение:
|
||
|
||
- `audit-cryptopro.ps1` -> Rust audit CLI;
|
||
- `run-user1-probe.ps1` -> Rust diagnostic probe or remove if obsolete;
|
||
- operator PowerShell profile is not production runtime and can be retired
|
||
after Rust/SSH operator commands exist;
|
||
- `.pssa_run.ps1` removed when no product PowerShell remains.
|
||
|
||
Gate:
|
||
|
||
- no production task/service depends on these helpers;
|
||
- docs no longer instruct operator to run PowerShell for routine checks;
|
||
- one emergency manual path remains documented, but not packaged as runtime.
|
||
|
||
### Phase 7. Decommission
|
||
|
||
Цель: убрать PowerShell from product surface.
|
||
|
||
Действия:
|
||
|
||
1. Remove `.ps1` from install-kit file list.
|
||
2. Remove `powershell.exe` installer run action.
|
||
3. Remove default `.ps1` paths from Ansible/bot env.
|
||
4. Update architecture/docs:
|
||
- Windows collectors are Rust EXE;
|
||
- PowerShell no longer prerequisite for runtime;
|
||
- rollback history documented separately.
|
||
5. Run tracked-file hygiene scan for public docs.
|
||
|
||
Gate:
|
||
|
||
```bash
|
||
rg -n "powershell\\.exe|\\.ps1|PowerShell" windows ansible docs scripts README.md
|
||
```
|
||
|
||
Expected result:
|
||
|
||
- only historical notes, explicit rollback docs, or non-runtime examples remain;
|
||
- no install-kit primary action launches PowerShell;
|
||
- no AWatch-rus Scheduled Task action launches PowerShell in live validation.
|
||
|
||
## 7. Rollout по хостам
|
||
|
||
Порядок раскатки:
|
||
|
||
1. Local build host:
|
||
- build Windows EXE;
|
||
- artifact check;
|
||
- installer dry-run.
|
||
2. Test Windows/RDP host:
|
||
- install Rust EXE side-by-side;
|
||
- shadow-mode collectors;
|
||
- compare with PowerShell.
|
||
3. Canary production Windows/RDP host:
|
||
- one host, one business day;
|
||
- monitor bucket freshness, DLP incidents, 1C upload, evidence upload.
|
||
4. Remaining Windows hosts:
|
||
- staged batches;
|
||
- no more than one failure domain at a time.
|
||
5. AW server / Proxmox / gateway:
|
||
- update Ansible/bot references;
|
||
- verify server Rust services remain active;
|
||
- verify ClickHouse ingest and portal health.
|
||
6. Install-kit:
|
||
- publish Rust-first package;
|
||
- keep previous package as rollback artifact.
|
||
|
||
## 8. Acceptance gates
|
||
|
||
Local gates:
|
||
|
||
```bash
|
||
cd adk-rust
|
||
cargo fmt --all -- --check
|
||
cargo test --workspace
|
||
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||
cargo build --workspace --release
|
||
cargo build --release --target x86_64-pc-windows-gnu -p awatch-agent-rs -p aw-windows-telemetry
|
||
```
|
||
|
||
Repository gates:
|
||
|
||
```bash
|
||
scripts/check_detmir_rust_release_artifacts.sh
|
||
scripts/verify_innosetup_installer.sh
|
||
git diff --check
|
||
```
|
||
|
||
Windows gates:
|
||
|
||
```powershell
|
||
Get-ScheduledTask | Where-Object {
|
||
$_.TaskName -like 'ActivityWatch*' -or $_.TaskName -like 'AWatch*'
|
||
} | Select-Object TaskName,TaskPath,State
|
||
```
|
||
|
||
Expected:
|
||
|
||
- task actions point to Rust EXE for migrated components;
|
||
- no migrated component runs `powershell.exe`;
|
||
- logs are fresh;
|
||
- spool is empty or draining;
|
||
- AW buckets are fresh;
|
||
- DLP evidence sync only uploads DLP incident evidence;
|
||
- 1C upload does not copy screenshots.
|
||
|
||
Server gates:
|
||
|
||
```bash
|
||
detmir-status --json
|
||
detmir-check --json
|
||
systemctl --failed --no-pager
|
||
systemctl list-timers aw-1c-ingest.timer --no-pager
|
||
```
|
||
|
||
Expected:
|
||
|
||
- AWatch-rus severity is OK or explained WARN;
|
||
- no failed Rust services;
|
||
- ClickHouse writer timer is active;
|
||
- portal data freshness is acceptable for pilot.
|
||
|
||
## 9. Rollback model
|
||
|
||
До decommission каждая миграция хранит rollback:
|
||
|
||
- previous EXE/script backup in `switch-backups`;
|
||
- previous task/service definition;
|
||
- previous `deployment-config.json`;
|
||
- one-command switch back for canary host;
|
||
- rollback reason written to audit log.
|
||
|
||
Rollback триггеры:
|
||
|
||
- AW bucket stale/dead after migration;
|
||
- DLP event loss or uncontrolled duplicate events;
|
||
- evidence upload fails repeatedly and spool grows;
|
||
- 1C upload stops producing landing files;
|
||
- service/guard restarts loop;
|
||
- Windows host shows sustained CPU/RAM regression from new EXE;
|
||
- user-visible pilot portal data quality degrades.
|
||
|
||
## 10. Риски
|
||
|
||
| Риск | Где | Снижение риска |
|
||
|---|---|---|
|
||
| Windows API differs from PowerShell cmdlets | DLP, tasks, Event Log, print, WMI | parity fixtures, canary, schema comparison |
|
||
| UIAutomation/browser URL extraction changes behavior | browser collector | shadow-mode and domain count comparison |
|
||
| Outlook/SMTP metadata behavior differs | email collector | metadata-only parity, explicit mode tests |
|
||
| Privilege mismatch | services/tasks/recovery | install under same account, explicit elevation, validation |
|
||
| AV/EDR blocks unsigned EXE | Windows hosts | code signing plan, allowlist, staged rollout |
|
||
| Duplicate events during shadow | all collectors | shadow source tags, portal ignores shadow for KPI |
|
||
| Rollback not fast enough | production canary | backup tasks/configs, single switch command |
|
||
| Public docs leak live contour details | tracked docs | placeholders and `git grep` hygiene scan |
|
||
|
||
## 11. Минимальный порядок ближайших работ
|
||
|
||
1. Зафиксировать live inventory PowerShell usage на тестовом Windows/RDP host.
|
||
2. Закрепить уже сделанные Rust paths:
|
||
- worktime/RDP;
|
||
- 1C file upload;
|
||
- DLP evidence sync.
|
||
3. Расширить `aw-windows-telemetry.exe validate-deployment` до полной parity с
|
||
`validate-deployment.ps1`, потому что он станет главным gate для следующих
|
||
замен.
|
||
4. Перенести `aw-standalone-service.ps1` и `aw-collector-guard.ps1`, потому
|
||
что они управляют runtime collectors.
|
||
5. Стабилизировать P0 runtime collectors после live Rust-primary switch:
|
||
- browser domains;
|
||
- DLP endpoint signals;
|
||
- file operations.
|
||
URL/domain extraction и clipboard/USB/print incident semantics закрыты на
|
||
уровне Rust code/schema/runtime self-test. Следующий шаг перед удалением
|
||
legacy `.ps1` - burn-in, canary rollback test и live foreground-browser
|
||
proof в интерактивной RDP-сессии.
|
||
6. Перенести deploy/install scripts и InnoSetup primary action.
|
||
7. Убрать PowerShell paths из Ansible/bot env.
|
||
8. Удалить `.ps1` из install-kit и оставить только historical rollback docs.
|
||
|
||
## 12. Итоговая оценка
|
||
|
||
Миграция реалистична, потому что серверная часть уже Rust-first, а Windows
|
||
контур уже имеет два рабочих Rust основания: `awatch-agent-rs` и
|
||
`aw-windows-telemetry.exe`.
|
||
|
||
Критичный участок не сервер, а Windows runtime и install-kit:
|
||
|
||
- `dlp-endpoint-signals-collector.ps1`;
|
||
- `browser-domains-native-collector.ps1`;
|
||
- `aw-collector-guard.ps1`;
|
||
- `aw-standalone-service.ps1`;
|
||
- `validate-deployment.ps1`;
|
||
- InnoSetup action that still launches PowerShell.
|
||
|
||
До пилота не нужно удалять весь PowerShell хвост. Для пилота достаточно
|
||
закрепить уже работающие Rust-primary paths, не допустить копирования
|
||
скриншотов в 1C контуре, оставить скриншоты только для DLP events, иметь
|
||
понятный rollback и честно формулировать границу parity: code/schema/runtime
|
||
path закрыт, а полный live URL/domain incident proof требует активного
|
||
foreground browser в интерактивной RDP-сессии.
|
||
Полное удаление PowerShell из install-kit лучше делать после canary и shadow
|
||
parity по DLP/browser/file collectors.
|