# Windows UX remediation and RC9 validation — 2026-09-07

All four findings from the [RC6 RDP review](WINDOWS_RDP_UX.md), its decorative
icon accessibility observation, and two additional issues discovered during
revalidation are fixed. The final candidate is **1.3.0-rc.9**, source `8a75f4e`,
built `2026-09-07T23:58:14Z`. This is candidate QA, not final release approval.

The [results](results-rc9.json) bind native checks to all six public executable
hashes and the exact [signed manifest](rc9-manifest.json). The Windows amd64
executable SHA256 is
`008f1274f087cf67b83f99edfa14f21dfc435caad26f91f41f81675ba924a9fb`.

## Environment and method

The owner explicitly designated the `agent` account on `win-dev` for QA. Tests
used its existing Windows 11 amd64 console session 1, standard-user processes,
actual profile, HKCU and default install directory. Original configuration was
snapshotted before mutation. No account was created, password changed, or HOME
redirected for these desktop tests.

Visible Edge 152.0.4191.66 was controlled over an SSH-forwarded local debugging
connection. Windows Settings and native player windows were controlled through
UI Automation and physical mouse events in that same desktop. This follow-up
used the active console, not a new RDP login. Browser screenshots and native
desktop captures were visually inspected. Product mutations used actual UI
controls; job responses, filesystem hashes and registry checks corroborated
results. The test video was a generated blue frame.

RC7 introduced the original fixes. Its native busy-player test exposed a job
callback race, fixed in RC8. RC8's full Edge route sweep then exposed retained
event streams in cached pages, fixed in RC9. The decisive Windows route and
install/uninstall checks below were repeated with RC9 and a fresh dedicated
Edge profile. Earlier candidates remain immutable historical evidence.

## Findings and verified fixes

| Finding | Change | Final evidence |
| --- | --- | --- |
| WUX-01: partial uninstall with mpv running | Native preflight checks every owned file before shortcuts, registration or payload removal; blocked operations explain closing mpv and retrying | Actual registered running player: all 11 owned files, 2 shortcuts, 4 registry branches and 18 config-related files unchanged. [State](rc9/busy-verification.json), [retry enabled](rc9/01-busy-refusal-retry-enabled.png) |
| WUX-02: cancelled job keeps an Installing toast | Live and reconciled cancellation remove the started toast and display a terminal result | UI cancellation acknowledged in 794 ms; exact staging directory removed, no payload installed, config preserved. Retry displayed one View Progress action. [UI](rc9/03-cancelled-clean-toast.png), [state](rc9/cancel-verification.json) |
| WUX-03: Running at 100% | Nonterminal overall progress is capped at 99; only successful completion reaches 100 | Actual dialog displayed Running (99%); install completed at 100. None of 140 recorded job events showed non-complete status at 100. [Dialog](rc9/04-running-99.png), [events](rc9/job-samples.jsonl) |
| WUX-04: overlay cancellation loses focus | Re-enable the invoker before the dialog restores focus | Actual MPV Install flow: Cancel and Escape both restored focus to the enabled Install button without starting a job; matching real-browser regression passes |
| Decorative icons enter accessible button names | Job-modal icons are hidden from accessibility APIs | Exact Close and Cancel Job accessible-name locators passed in real Chromium and actual Windows Edge |
| RC7 discovery: fast failure leaves Uninstall disabled | Resolve completion callbacks registered after a terminal SSE event, including retained job lookup; deliver once | Busy refusal finished in 2.5 ms; retry button recovered without refresh and retry succeeded after closing the player. The real-browser regression deliberately holds the start response until completion arrives |
| RC8 discovery: navigation stalls after cached pages retain SSE connections | Disconnect on pagehide, cancel owned reconnect timers, reconnect and reconcile on persisted pageshow | RC9 completed all 22 Windows route checks in 142–758 ms each, and restored a live stream on cached Back. Navigation during install returned through the cache to the installed card. [Route results](rc9/windows-application.json), [active task](rc9/05-navigation-during-install.png) |

Busy-file preflight is not an atomic transaction across multiple files. An
external actor can change access after the scan; existing inventory retention
and retry handling remain necessary for later removal failures. Actual Windows
package tests separately passed running-image, locked-FFmpeg and read-only-file
cases, preserving payload and shortcuts before refusal. The
[native test log](rc9/native-preflight.log) comes from the RC7 test binary; that
installer implementation is unchanged in RC9.

## Actual Windows workflow

Uninstall confirmation Cancel restored focus and started no job. With registered
mpv playing, uninstall refused safely with close-and-retry guidance. Closing the
native player and retrying without refreshing completed removal in 195 ms:
all 11 owned files, 2 shortcuts and 4 native registration branches were absent;
all 18 config-related files were unchanged. See
[uninstall state](rc9/uninstall-verification.json).

After the cancelled download, the retry installed mpv, FFmpeg and ModernZ in
21.7 seconds. Dashboard/Tasks navigation left the worker running. Returning to
Apps through the browser cache restored the stream and showed the completed
installation. Set default app returned success and registered 72 supported
types, including AAC and MKV. See the
[final card](rc9/07-final-install-registered.png),
[four jobs](rc9/windows-jobs.json), and
[final state](rc9/final-install-verification.json).

During RC8, the same native registration implementation was also tested through
the actual [.mkv chooser](rc9/rc8-chooser-mkv.png) and
[.aac chooser](rc9/rc8-chooser-aac.png). Selecting mpv updated the visible Windows
defaults for both types, and shell-opening the generated MKV launched the
installed player and displayed the [video](rc9/rc8-shell-playback.png).
Registered uninstall removed native entries and a subsequent shell open did
not launch mpv. These are supplementary RC8 observations, not repeated RC9
default-selection claims. RC9's final state verifies registration; selection of
file defaults remains a Windows user action.

The RC9 UI shutdown returned HTTP 200; logs recorded server and SSE shutdown,
and the QA manager process exited. Original non-runtime configuration remained
byte-identical across the complete exercise: 13 files, including mpv.conf SHA256
`803970cf32e5316e3ebe8b048351c73b05588ae5ceb43b2b7cd6d0620716d7a6`.
Manager runtime files, including release trust state advancing to RC9, were
excluded from that original-config comparison. The busy/refusal and successful
uninstall comparisons used their own immediate baseline and preserved all
18 config-related files in that baseline.

## Regression and publication validation

- Full Go tests and race suite passed; pinned vet/Staticcheck lint passed.
- All 182 Vitest tests and vendor freshness passed. Frontend generation ran
  after template edits; generated CSS remained unchanged.
- All 13 real-browser tests passed. Two use full Chromium with back-forward
  caching enabled: one asserts a single backend SSE client across navigation
  and Back; the other completes a job while away and verifies cached-page
  reconciliation and one callback. The former failed against RC8 before the fix.
- Native RC9 applications on Windows amd64, macOS arm64 and Linux amd64 each
  passed 22 route checks at phone/desktop widths, authenticated RC metadata,
  rejection of unauthenticated API access (401), no page errors and shutdown.
- All six release targets built. Public executable SHA256, signed BLAKE3 and
  size matched the local builds. The public RC feed matched signed output
  byte-for-byte; 16 reviewed upstream inputs and six unchanged mirrors were
  verified. Legacy feed bytes were preserved during publication, its timer
  remained active, and no stable manifest was published.

The native harness recorded two assertion corrections: a Playwright Back call
waited for a new load event on a restored cached document, although the document
was complete, persisted and live; the registration assertion initially expected
`success: true` instead of the actual `status: "success"` response. Direct page,
job and registry checks confirmed both product outcomes. During RC8, checking
an older UserChoice registry location did not reflect the visible Windows
default selection; actual Settings labels and shell playback supplied the
default-app evidence. These harness observations are distinct from the two
product defects fixed in RC8 and RC9.

## Cleanup and remaining scope

All 33 temporary scheduled tasks, three QA roots, QA browser/manager processes
and the debugging tunnel were removed or closed. Original config snapshots were
retained privately before removing the VM QA roots. The active `agent` desktop
and managed mpv + FFmpeg + ModernZ installation remain, with native registration
and original configuration intact. See [cleanup](rc9/cleanup.json).

This pass does not establish elevated/HKLM behavior, Windows arm64/macOS
Intel/Linux arm64 native behavior, unsigned browser-download permission gates,
physical GPU qualification, or final owner acceptance. Those separate gates
remain in [release readiness](../../RELEASE_READINESS_v1.3.0.md).
Changes and evidence are committed locally; no Git push, tag or stable
publication is part of this remediation.
