# Provisioned Windows test VM This page is the authoritative record for the resettable Windows smoke fixture. It describes the machine that is available today; it is not the complete Windows release matrix. Keep the values here in sync with the VM before adding or changing native test automation. Last configuration check: 2026-09-09 UTC. The VM was observed powered off with `baseline-clean-administrator` selected. The native harness targets that snapshot; the fixture is ready for native runs. A test run must still perform its own identity, snapshot, readiness, and exclusive-lease checks rather than relying on that observation. ## Identity and access | Item | Value | | --- | --- | | Test VM | `rvbox-win10-test` | | VM UUID | `6cdc114f-71e5-4167-a394-e922e14e6f5c` | | VM group | `/RVBox/Tests` | | VirtualBox host | SSH alias `helium-remote`; host address `192.168.50.162`; host user `cabbage` | | Host platform | Arch Linux; kernel `7.2.2-arch1-1`; VirtualBox `7.2.16r174877` | | VM configuration | `/home/cabbage/VirtualBox VMs/RVBox/Tests/rvbox-win10-test/rvbox-win10-test.vbox` | | VM logs | `/home/cabbage/VirtualBox VMs/RVBox/Tests/rvbox-win10-test/Logs` | | Snapshot folder | `/home/cabbage/VirtualBox VMs/RVBox/Tests/rvbox-win10-test/Snapshots` | | Guest OS | Windows 10 Pro 22H2, build `19045.2006`, en-US, BIOS boot | | Guest account | Local `rvboxtest`; split-token local administrator; console session 1 was observed during provisioning | | Guest Additions | `7.2.16r174877`; readiness requires published Guest Additions version and Windows OS-release properties (this build does not publish a RunLevel property) | | Last observed state | `poweroff`; current snapshot `baseline-clean-administrator`, the reset target for native runs | The two fixture accounts deliberately share one fixed test-only password for reproducible native runs. The value is provisioned only in the Helium host's mode-600 file and is never committed; agents use the documented file contract rather than re-entering or varying it. These credentials are valid only for this isolated disposable VM and must never be reused outside it. The controller reads the same value for both accounts from: ```text /home/cabbage/.local/share/rvbox-secrets/rvbox-win10-test.password ``` The file must be mode `0600` and is supplied to VirtualBox only with `--passwordfile`; the controller never places it on a command line, run manifest, log, or artifact. The SSH key and the Helium host account credential remain private and are not part of this test-only credential exception. ## Hardware and device profile | Item | Value | | --- | --- | | Memory / CPUs | 4096 MiB RAM; 2 vCPUs; 100% execution cap; host CPU profile | | Display | `VBoxSVGA`; 64 MiB VRAM; 3D acceleration disabled | | Firmware / boot | BIOS; disk first, DVD second; install media is detached after provisioning | | System disk | 40 GiB dynamically allocated VDI; logical base path `/home/cabbage/VMs/rvbox-win10-test.vdi`; active snapshot differencing disks live under the snapshot folder above | | Install media | `/media/Data2/Downloaded/Win10_22H2_English_x64.iso`, Windows image index 6 | | Audio | Virtual audio disabled (`audio=none`, playback and capture off) | | USB | OHCI, EHCI, and xHCI disabled; no USB filters | | Clipboard / drag and drop | Disabled, including clipboard file transfers | | Network adapter | One Intel 82540EM adapter, cable connected, NAT attachment; MAC `080027036E7C` | | Shared folders | None; there is no shared-folder contract for tests | This is a minimum smoke profile (2 vCPU/4 GiB), not the recommended release host profile. It is suitable for bounded tests and may be too small for long parallel suites. ## Network and remote-control endpoints The guest address is assigned by VirtualBox NAT/DHCP. `10.0.2.15` was the last observed guest IPv4 address, but it is not a stable identity and must not be hard-coded into a harness. | Endpoint | Configuration and use | | --- | --- | | Host management | SSH to `helium-remote`, then invoke `VBoxManage`; do not assume `VBoxManage` is installed on the Linux controller | | Guest management | VirtualBox Guest Control over the host; use explicit executable/argument vectors and the password file above | | VRDE (VirtualBox RDP) | Enabled for diagnostics on Helium loopback at `127.0.0.1:3389`; external authentication, `VBoxAuthSimple` user `rvboxtest`, `Security/Method=negotiate`, single connection reuse, multiconnection off. Reach it only through an explicitly temporary, private SSH forward. | | VRDE TLS material | Auto-generated certificate and private key under `/home/cabbage/VirtualBox VMs/RVBox/Tests/rvbox-win10-test/`; keep both on Helium and do not copy them into the repository or test artifacts | | VRDE channels | Input/display enabled; audio, upstream audio, USB, clipboard, and RDP device redirection disabled; no video channel | | Native Windows RDP forward | NAT rule `rvbox-rdp`: host `192.168.50.162:3390` to guest port `3389` | | Native Windows RDP state | Disabled in the baseline (`TermService` stopped and `fDenyTSConnections=1`); do not treat port 3390 as usable until a test explicitly enables and later restores it | VRDE is not the supported test-control channel. It is retained for bounded diagnostic probes only: some RDP clients negotiate input capabilities that VirtualBox 7.2.16 does not handle reliably, and earlier probes included headless-server crashes. Use Guest Control for deterministic setup, execution, and collection. Do not expose the VM's RDP endpoints beyond the test LAN. For the rare interactive UAC/manual-recovery step, use the Docker-only helper in [`test/rdp-access`](../test/rdp-access/README.md). It creates a temporary self-signed HTTPS Guacamole gateway while retaining VRDE on Helium loopback and the reconnecting SSH watchdog/tunnel on a private Docker gateway. Follow its full lease/prepare/up/ down/reset lifecycle; it is not an alternative to the native test controller. In public-bind mode the helper also owns a tracked IPv6-to-IPv4 `socat` forward when the browser hostname has an AAAA record; check `ipv6_forward=active` in `rdp-access status` before diagnosing a browser-side “Waiting for response”. ## Snapshots and reset contract Three clean snapshots exist and must be retained. `baseline-clean-administrator` is the only reset target: it contains no `RVBoxClient` SCM service, RVBox tray Run-key registration, RVBox state, logs, or staged binaries; it also has the fixture-only built-in `Administrator` account enabled for high-token Guest Control installation. | Snapshot | UUID | Description | | --- | --- | --- | | `baseline-clean` | `5e79176a-3e56-4c5d-bb61-a405a6dcdd59` | `baseline-windows10-pro-22h2-rvboxtest-guest-additions` | | `baseline-disk-first` | `9430a9a4-754a-4b22-beaa-8dfd90043f5b` | `baseline-windows10-pro-22h2-disk-first`; retained diagnostic snapshot | | `baseline-clean-administrator` | `ba5ce5f1-77e3-44b0-8d91-534becce27ff` | `baseline-windows10-pro-22h2-administrator-enabled-full-token`; current reset target | Restore only while the VM is powered off. Every destructive or potentially stateful run must: 1. Acquire the run lease and verify the VM name, UUID, and snapshot UUID. 2. Restore `baseline-clean-administrator` if the current state is not the baseline. 3. Start headless and wait for `VMState=running` plus Guest Additions readiness. 4. Apply the disposable display/sleep keepalive (`monitor-timeout`, standby, and hibernate timers set to zero) so VirtualBox VRDE cannot expose a zero-bpp framebuffer after Windows idle timeout. This is recorded as `prepare-display-keepalive` and is reapplied after every snapshot restore. 5. Run the bounded test, collect redacted artifacts, and close every Guest Control process that was opened by the run. 6. Request a graceful guest shutdown and wait for `VMState=poweroff`. 7. Restore `baseline-clean-administrator` again and leave the VM powered off. Use `controlvm ... poweroff` only for a hung, disposable test; it can lose guest state. Never delete any clean snapshot, unregister the VM, or alter the stale unregistered `win10_dev` configuration (its disk is missing). ## Harness contract The canonical adapter is the POSIX controller script [`scripts/windows/test-host`](../scripts/windows/test-host). It runs from the Linux controller and invokes `VBoxManage` only through SSH on Helium; the fixture host is Arch Linux and does not provide PowerShell. Its actions are `status`, `prepare`, `stage`, `install`, `run`, `collect`, `stop`, `reset`, and `recover`. The legacy [`test-host.ps1`](../scripts/windows/test-host.ps1) is retained only as a reference for a future Windows-hosted fixture and is not the Helium lane. The adapter takes identity and credentials only from its environment: ```sh export RVBOX_TEST_VBOX_HOST=helium-remote export RVBOX_TEST_VBOX_VM=rvbox-win10-test export RVBOX_TEST_VBOX_VM_UUID=6cdc114f-71e5-4167-a394-e922e14e6f5c export RVBOX_TEST_VBOX_SNAPSHOT=baseline-clean-administrator export RVBOX_TEST_VBOX_SNAPSHOT_UUID=ba5ce5f1-77e3-44b0-8d91-534becce27ff export RVBOX_TEST_GUEST_USER=rvboxtest export RVBOX_TEST_GUEST_PASSWORD_FILE=/home/cabbage/.local/share/rvbox-secrets/rvbox-win10-test.password # Defaults to Administrator and the same password file; overrides are optional. export RVBOX_TEST_PROVISIONER_USER=Administrator export RVBOX_TEST_PROVISIONER_PASSWORD_FILE=/home/cabbage/.local/share/rvbox-secrets/rvbox-win10-test.password ``` Those values are the controller defaults for this one documented fixture, so a normal Helium run does not need to export them. They remain overrideable for a separately recorded fixture. The default contains only the host-local password *file path*, never the password value. The provisioned lane's backend is SSH plus `VBoxManage` plus Guest Control; it does not require WinRM, OpenSSH inside Windows, or a stable guest IP. The adapter first validates the VM and snapshot UUIDs, acquires its exclusive lease on Helium, and writes a non-secret step report to the run directory. Guest commands use exact console-safe executable paths and argument vectors. With this VirtualBox build, `--wait-stdout` and `--wait-stderr` are supported but `--wait-exit` is not; use `closeprocess` when a process wait cannot complete. For `cmd.exe` payloads, include `--unquoted-args` so Windows backslashes and the single `/c` payload are preserved. `stage` accepts one versioned non-secret test bundle and copies it first to an exact host staging directory, then to `C:\\ProgramData\\RVBox\\test-runs\\`. `install` performs the one purposeful direct Guest Control launch of the staged GUI-subsystem executable, using only the fixture provisioner's high token; because this VirtualBox build cannot reliably report that process's exit, SCM `RUNNING` is the completion proof. After installation, `run` uses `sc.exe` and other console-safe management tools to reconfigure/start/query/stop the installed RVBox service, then checks the service's real health endpoint, named-pipe response, durable state, and agent-server results. Before a WSS scenario it performs a bounded guest-to-nginx connectivity and CA-trust probe. The resulting service and artifact paths are recorded in the run report and reclaimed by the snapshot reset rather than broad guest deletion. The first-class end-to-end controller is scripts/windows/native-test run --run-id ID. It runs the per-run Linux server and nginx stack in Docker Compose under test/linux-server on the current controller. Helium hosts only the Windows VM and VirtualBox Guest Control bridge. The client connects to the explicit current-controller WSS endpoint (x1.xcel.me by default), never the DHCP guest address, and intentionally accepts that endpoint's matching-host self-signed certificate in v1. The controller drives requests with the local stack's rvc, collects bounded artifacts, and deletes just its labeled Compose project during cleanup. The test bundle never sends a Windows executable over the controller-to-Helium SSH hop. The tagged fixture build strips symbol and DWARF tables; `test-host stage` creates a temporary `xz -3` payload, publishes it to the authenticated controller HTTP endpoint, and directs Helium to download it through its SOCKS5 acceleration proxy. Helium resumes the HTTP payload, verifies its compressed SHA-256, atomically decompresses it into the exact host stage, then validates the ordinary uncompressed bundle manifest before Guest Control copies files into Windows. The baseline Helium host must provide `curl` and `xz`. Small non-secret `client.toml` and optional CA files still use bounded-retry SSH copies; executable staging fails closed if the accelerated route is unavailable. Each successful stage prints `verified transfer_sha256` and the verified manifest. No manual remote checksum check is needed for a normal or resumed test run. The controller uses bounded SSH retries (four attempts, short backoff) for idempotent inspection, staging, installation, and service-run operations. Reset, stop, and logoff intentionally remain single-attempt; after an interrupted lifecycle transition, use `recover` and decide whether to resume or reset instead of replaying an ambiguous action. For this controller/Helium fixture, the required executable route publishes only the stripped, compressed test executable under the current controller's Downloads HTTP endpoint (`http://x1.xcel.me:9124`, authentication `x1:x1`) and asks Helium to fetch it through its metered `socks5h://127.0.0.1:1085` proxy. The endpoint currently advertises Basic authentication, so the harness deliberately uses curl's `--anyauth` negotiation rather than assuming Digest. It never publishes `client.toml`, CA material, passwords, or other configuration. Helium resumes the HTTP download, verifies the compressed SHA-256, atomically decompresses it into its stage, and the ordinary manifest check still runs before Guest Control copies files into Windows. The uniquely named published artifact is removed after successful guest staging (and on a subsequently failed stage). `RVBOX_TEST_ACCEL_HTTP_URL`, `RVBOX_TEST_ACCEL_HTTP_AUTH`, `RVBOX_TEST_ACCEL_HTTP_PUBLISH_DIR`, and `RVBOX_TEST_ACCEL_SOCKS5` override the documented fixture defaults. Early Windows-service failures are appended to `C:\ProgramData\RVBox\service-startup.log`, before client config, durable state, or normal observability logging begins. This is intentionally outside a per-run bundle directory so the LocalSystem service can report an ACL/path failure affecting that directory. To prove the complete elevated fallback chain in one single-user fixture, the controller builds a separately tagged disposable rvbox.exe. Its only extra behavior is the internal --test-fail-contexts switch, which can force ACTIVE_USER_ELEVATED and then ACTIVE_SYSTEM token preparation to fail before launch. Release binaries reject the switch. The normal active-user, active-user-elevated, active-system, local-system, local-service, and logged-out local-system rows are therefore observed through the real SCM service without adding a product broker or protocol field. ### Clean baseline and non-interactive installation `rvboxtest` deliberately remains a split-token administrator. Guest Control therefore launches it at medium integrity and it must never be used to create or modify machine-wide SCM state. The reset snapshot has no RVBox installation. To automate the real install path, use the Windows built-in `Administrator` account as a separate **fixture-only** provisioning identity. It is enabled only on this disposable VM, has its documented fixed test password, and keeps `FilterAdministratorToken=0` (the normal Windows 10 default), and verify that Guest Control gives it a High Mandatory Level. This is the per-account exception that preserves UAC for `rvboxtest`; do **not** globally disable Admin Approval Mode or change `rvboxtest` into an always-elevated user. The normal harness defaults to this identity and same password file: ```sh export RVBOX_TEST_PROVISIONER_USER=Administrator export RVBOX_TEST_PROVISIONER_PASSWORD_FILE=/home/cabbage/.local/share/rvbox-secrets/rvbox-win10-test.password ``` If a policy or hardening configuration makes this account medium-integrity, the harness fails closed; do not replace it with a UAC-bypass mechanism. The host file remains mode `0600` and the value is not recorded in run reports or artifacts. `test-host install` first verifies that the reset guest has no `RVBoxClient`, checks the provisioner's High Mandatory Level, invokes the actual staged `rvbox.exe --install-service --config ...`, and polls SCM for `RUNNING`. It then checks that the provisioning account is no longer present in `query user`. A lingering Administrator session could become a second WTS candidate and contaminate `ACTIVE_USER` / `ACTIVE_USER_ELEVATED` tests, so the harness fails before command dispatch and the run must reset. `run` may then exercise reconfigure/start/restart paths. Snapshot reset removes the installed service and all RVBox data again. The provisioner is fixture administration only: it is not shipped with RVBox, not a product service/broker, not a Task Scheduler dependency, and never participates in command-context selection. The separately interactive UAC prompt route remains a small manual test because an invisible Guest Control session cannot safely approve a consent prompt. ## Scope and known limitations This fixture currently provides one active console user and no standard-user, ambiguous multi-session, Server Core, older-build, or physical hardware variant. Those release-matrix entries remain deferred; their selector and fallback unit tests are still required. The GUI-subsystem Guest Control probe also exposed a completion-path limitation for `rvbox.exe`; native runtime coverage must use a service-driven/console-compatible runner until that adapter path is completed. Wine and protocol stubs do not count as Windows coverage. For a complete command sequence and lifecycle examples, see the provisioned lane section in [`implementation-plan.v1.md`](implementation-plan.v1.md) and the general [testing workflow](testing.md).