feat(rust): advance powershell migration
This commit is contained in:
@@ -0,0 +1,616 @@
|
||||
# Roadmap: замена PowerShell на Rust EXE
|
||||
|
||||
Дата: 2026-06-05
|
||||
|
||||
Цель: убрать зависимость AWatch-rus/DetMir от 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.
|
||||
- Основные серверные DetMir/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:
|
||||
|
||||
- DetMir 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.
|
||||
Reference in New Issue
Block a user