# Testing

The repository uses Go tests for backend/TUI behavior, Vitest for frontend
components and contracts, build checks for embedded assets, and native-device
qualification for platform update behavior.

## Required local baseline

Run this before committing a broad change:

```bash
go test ./...
go test -race ./...
go vet ./...
test -z "$(gofmt -l pkg cmd internal)"
go mod tidy -diff
go mod verify
npm run vendor:frontend:check
npm test
npm audit --package-lock-only --audit-level=high
```

For release-affecting changes, also run:

```bash
make build
make build-all-parallel VERSION=1.3.0
```

`govulncheck ./...` is required when dependencies or reachable code change.
GitLab CI installs the pinned scanner version declared in `.gitlab-ci.yml`.

## Focused suites

```bash
# Signed manifest, updater identity, transaction helper, recovery, and rollback
go test -v ./pkg/version

# Shared release schema plus publisher/verifier/key tooling
go test -v ./pkg/releasemanifest ./cmd/generate-info ./cmd/verify-manifest ./cmd/manifest-keygen

# Web APIs, middleware, jobs/SSE, lifecycle, and templates
go test -v ./pkg/web

# Bubble Tea models and terminal workflows
go test -v ./pkg/tui

# Installers and platform behavior
go test -v ./pkg/installer ./pkg/platform

# Persisted shared job history
go test -v ./pkg/jobhistory

# Cross-process file/config coordination and migration recovery
go test -v ./internal/fileops ./pkg/config ./pkg/uiconfig

# Frontend component and static contracts
npm test
```

Use `-run` for one regression and `-count=1` when cached results are
undesirable. Use `-race` on concurrency-sensitive packages.

Release-tool regressions parse `.gitlab-ci.yml` and protect the isolated-signer
contract, digest-pinned images, protected SemVer policy, serialized immutable
publication, exact native-evidence gate, Windows resource inspection,
notice-bearing archives, and executable `b3sum -c` format. Generator download
tests cover declared oversize rejection, truncated and idle body cleanup,
bounded retries, pipeline-local manager hashing, and environment-proxy support.

Installer regressions include native ZIP/tar/gzip/xz/7z extraction, traversal
and link/special-file refusal, Windows case collisions, file-as-parent and
expanded-size limits, uOSC inventory allowlisting, preservation of unrelated
live files, and injected commit failures. Crash-recovery tests persist
interrupted overlay/new-file/UI journals, release their process locks, invoke
startup recovery, and prove restoration/removal behavior. They also prove that
committed journals preserve the replacement and that tampered out-of-scope
paths are rejected without touching the referenced file.
Missing-backup fixtures preserve all live targets, and repeated file/directory
rollback retains original backups until a durable terminal journal is written.
UI preparation tests edit the live configuration during staging, cancel before
commit, and recover both component versions and clean baselines after an
interrupted commit. Closing a prepared UI prevents later activation.

`internal/process` tests own native child lifetimes, including a parent that
exits while its child retains an output pipe. `internal/packagequery` uses a
native executable fixture to verify locale, parsed versions, stderr absence,
timeouts, and oversized diagnostics. Unknown results never remove app records.
These packages can be cross-compiled with `go test -c` and run on the target OS.
Web/TUI lifecycle tests verify cancellation during preparation, commit draining,
and shutdown waiting for workers and leased mutations. Reconciliation route
tests exercise the actual HTTP registrations while an install owns the lease.

Configuration/history regressions include a real helper-process advisory-lock
contention check, independent job-history stores appending without lost
records, durable corrupt-history quarantine, latest-disk manager-config
rebasing, flat backup containment with a symlinked `conf_backups` directory,
and both uncommitted/committed ModernZ migration-journal recovery branches.
The shared `internal/mpvconf` parser covers default/profile scope, last-assignment
semantics, literal quoting, scalar commas, and BOM/CRLF preservation. A Web
settings/Apply round-trip regression verifies those values survive a save and
that named profile overrides and file permissions are retained.

CLI/PATH/parser/listener regressions cover rejected ignored destinations,
mode/positional conflicts, startup-time verbose stderr output, quoted hashes in
`mpv.conf`, `input.conf`, and script options, BOM/CRLF/mode preservation,
script-option symlink refusal, repeated Unix PATH installation/removal and
rollback, synchronous listener readiness, occupied-port non-publication, and
concurrent-start single ownership. Windows amd64/arm64 compile gates exercise
the current-user registry PATH implementation; native Windows registry
mutation remains a release smoke gate.

Web stream/request regressions cover terminal-event priority under a full
client queue, connect/reconnect active-plus-recent snapshots, broadcaster
closure and late-client rejection, persistent-stream shutdown without waiting
for the HTTP deadline, per-key UI-setting request ordering, missed-terminal
browser reconciliation, and monotonic regional-language controller ownership.

Platform discovery regressions prove that Windows scans never execute a
candidate binary; Linux package probes use a C locale with bounded time and
output; unknown observations preserve tracked records; exact not-found
observations remove only one method/path identity; and multiple same-method
installations coexist. MPC-QT tests cover elevated wait/exit propagation and
post-install executable discovery, with Windows cross-compilation guarding the
native call path. GPU tests aggregate GLX/Vulkan/PCI adapters, preserve
trademark-decorated models, resolve PCI IDs, combine hybrid codec capabilities,
and keep VA/NV flags per adapter. Hotkey/locale tests cover duplicate mutation,
reserved comment keys, canonical 2-/3-letter codes, common-code resolution,
unique locale IDs, and corrected regional metadata.

## Frontend and embedded assets

Exact htmx and Alpine versions live in `package.json` and `package-lock.json`.
The reviewed distributions are copied into the Go-embedded tree.

```bash
npm ci
npm run vendor:frontend:check
npm test
npx tailwindcss -i ./internal/webassets/css/input.css -o /tmp/tailwind.min.css --minify
diff /tmp/tailwind.min.css internal/webassets/static/css/tailwind.min.css
```

The frontend suite covers Alpine component state, accessible dialog behavior,
template semantics, contrast/touch-target contracts, dependency loading, and
the manager-update restart modal's non-dismissible policy. Frontend test sources
remain outside the Go runtime embed; an asset regression checks that they cannot
be served while shipped scripts, styles, icons and vendor files remain available.

`npm run test:browser -- tests/browser/october-regressions.spec.mjs` covers custom
Config values and clear/apply/reload through real HTTP handlers, held details
responses around completion/error/cancellation SSE, reordered selections and
modal close, idle Tasks tabs, adoption completion card swaps, Settings request
counts, and actual Alpine priority-list teardown. Adoption admission is controlled
by a fixture; its job worker, config publication, SSE and htmx card rendering use
the real Go server. This does not qualify native adoption or platform installs.

## Release identity test

The CI `version-identity` job performs a real sentinel-linked build and checks
the JSON identity. The equivalent local smoke check is:

```bash
make build VERSION=v9.9.9-ci
./dist/mpv-manager --version --json
```

Verify exact `product`, `component`, normalized `version`, `goos`, and
`goarch`. Unit tests also prove that staged binaries with a wrong product,
component, version, OS, architecture, invalid JSON, non-zero exit, or failed
execution are rejected and rolled back.

## Self-update regression matrix

Automated portable-binary tests must cover:

- manifest/check failure and missing platform asset;
- unsigned, untrusted, tampered, malformed, oversized, and wrong-version manifests;
- strict tag-bound release-provenance locks, reviewed upstream digest mismatch,
  and pipeline-local manager artifact hashing;
- download failure, size bound, and BLAKE3 mismatch;
- exact identity success and every identity mismatch;
- cross-process lock contention and unique transaction paths;
- one-download primary/secondary staging with authenticated size/hash checks;
- helper-host validation, post-exit apply, per-target outcomes, and partial-target rollback;
- digest-before-exec ordering, never-absent platform replacement, mandatory
  backup evidence, and restored digest/identity verification;
- interrupted apply recovery and committed/prepared cleanup;
- authenticated journal tamper rejection, refusal of legacy journals and missing
  original evidence before backup execution, and missing-key evidence retention;
- private authentication-key creation and reuse; Unix ownership/mode checks and
  Windows DACL checks (the Windows cases require native execution);
- permission/post-swap failure and rollback;
- structured phases: `checking`, `downloading`, `verifying`, `committed`,
  `ready_to_restart`, `restarting`, `rolled_back`, and `failed`;
- one immutable release selection from check through install;
- Web background-job success/failure and duplicate rejection;
- worker-acknowledged cancellation, retained leases while stopping, commit-bound cancellation rejection, and partial-success persistence;
- cross-method resource conflicts between background jobs and direct config/UI requests;
- backend-owned shutdown after success and no shutdown after failure;
- graceful Web closure returning exit status 0;
- TUI completion, manager/client classification, Escape policy, restart,
  relaunch failure, and retry;
- post-first-render TUI health acknowledgement and a Linux native-PTY check
  proving that rendered output and terminal input survive helper relaunch;
- TUI Escape/Ctrl+C cancellation waits for worker shutdown, terminal results
  cannot overtake trailing output, and list-filter Enter/Escape cannot dispatch
  the selected action;
- TUI UI changes select an exact stable app identity, mutate only its config
  tree/metadata, and do not create a duplicate installed-app record;
- TUI operation panics become terminal results; TUI command runners reject
  interactive sudo; output/history CSI, OSC, C0, and C1 controls are removed
  before persistence/rendering;
- TUI output retention, keyboard auto-follow control, all-list resize reflow,
  Unicode deletion, fractional progress, and exact-ID MPC-QT version updates;
- one asynchronous TUI release manifest refresh populates both installer and
  manager-update state, with an explicit tested offline failure state;
- CLI success/failure exit behavior, argument-contract errors, and custom-path
  support only for destination-aware methods;
- Web browser/banner launch only after successful synchronous listener bind.

The current-process Web shutdown path can be probed manually with a temporary
cookie jar because all APIs require the per-start auth cookie:

```bash
./dist/mpv-manager web --web-open=false --web-port 6797
# In another terminal:
curl -c /tmp/mpv-manager-cookie http://127.0.0.1:6797/
curl -b /tmp/mpv-manager-cookie -X POST http://127.0.0.1:6797/api/shutdown
```

The server process must exit 0 without printing `Web server failed: <nil>`.
Remove the temporary cookie jar afterward.

## Browser smoke review

For Web UI changes, run the application and inspect every primary route at
320, 390, 768, and 1024 CSS pixels. Check:

- no horizontal overflow;
- exactly one page-level H1;
- keyboard focus and Escape behavior for dialogs;
- 44 px touch targets where applicable;
- readable computed contrast on actual rendered surfaces;
- HTMX navigation and partial replacement;
- job creation, SSE progress, completion, error, and reconnect behavior;
- zero unexpected console errors and failed network requests.

The automated full jobs/SSE browser workflow is tracked in Atlas task
`9f8175f3`.

The 2026-08-30 live Chromium release smoke covered all 11 primary routes,
mobile (390 × 844) and desktop (1280 × 800) layouts, page-heading and landmark
ownership, horizontal overflow, 44 px mobile controls, Tasks/Settings Alpine
initialization, authenticated status/jobs APIs, and clean console/network
diagnostics. The server-backed update-ready modal remained visible past the old
premature-close deadline, was non-dismissible, instructed the user to restart,
counted down for five seconds, and issued exactly one shutdown request. The
final non-intercepted shutdown returned HTTP 200 and the Linux process exited
with status 0. This smoke complements rather than replaces the full job/SSE E2E
task above.

## Native release gates

For v1.3.0, Microsoft Authenticode and Apple Developer ID/notarization are
deferred to v1.4.0 by the owner's 2026-09-06 decision. Qualify the actual
unsigned launch/quarantine/permission behavior; verified-publisher and
notarized-policy acceptance belong to v1.4. See the
[current release checklist](RELEASE_READINESS_v1.3.0.md) for exact scope,
hardware coverage handling and remaining tasks. Manifest trust checks remain
required. Physical GPU coverage relies on user reports per owner decision.

Cross-compilation proves source portability, not native update behavior.
Before v1.3.0, qualify release artifacts on:

- `win-dev`: Windows 10/11 behavior, amd64 and arm64 artifacts as hardware
  permits, writable/unwritable destinations, file locks, permissions,
  rollback, relaunch, Web notice, and exit status;
- `macos-dev`: Apple Silicon native behavior plus Intel artifact validation,
  permissions, quarantine/signature policy, rollback, relaunch, Web notice,
  and exit status;
- Linux amd64/arm64: portable writable/unwritable paths, package-managed
  self-update disabled, rollback, relaunch, and shutdown.

Also test N-2 and N-1 upgrades to N and all release-manifest failure cases.
Atlas task `5a0590af` records the completed current-protocol native matrix;
final published-artifact and policy gates remain under `b7ef5143`.

For a tag pipeline, retain the immutable native run/signature evidence, record
the exact SHA-256 of each Windows/macOS build-job artifact, and approve the
protected `native:evidence` environment only when its tag/commit/digests match.
Registry publication cannot start before that manual binding succeeds.

For the safe, repeatable transaction-mechanics subset, run:

```bash
make qualify-selfupdate
```

The development-only qualifier creates disposable primary/secondary targets
and isolated configuration, then covers pre-commit hash/length rejection,
commit, partial-apply rollback, cross-process lock contention, healthy relaunch,
and failed-health rollback.
It uses two synthetic versions built from the current source; it does not
replace the separate historical N-1/N-2 artifact, signing, permissions, or
browser-lifecycle gates. Its scope and dated native results are recorded in
[Self-update and Wails Review](SELF_UPDATE_AND_WAILS_REVIEW_2026-08-28.md#native-qualification-harness-and-current-results).
The Make target supplies the private `selfupdate_qualification` build tag;
ordinary and release builds do not contain the synthetic-selection bypass.

The original five transaction cases passed natively on Linux amd64, Windows 11
amd64, and macOS Apple Silicon on 2026-08-30. The two pre-commit rejection cases
were added on 2026-08-31; their platform results are recorded in the updater
review. The remaining release gates concern historical artifacts, additional
architectures, signing/quarantine/ACL policy, unwritable/package-owned
installations, and final published artifacts.

## Coverage and test data

Generate current coverage rather than copying percentages into docs:

```bash
go test -coverprofile=coverage.out ./...
go tool cover -func=coverage.out
go tool cover -html=coverage.out
```

Tests must use `t.TempDir`, temporary config homes, local `httptest` servers,
and injected hooks. Never point destructive installer or updater tests at a
real installation. Keep fixtures small and deterministic.

---

See also: [Build and Deployment](BUILD_DEPLOYMENT.md) · [Troubleshooting](TROUBLESHOOTING.md) · [Project README](../README.md)

## Browser job and lifecycle integration

`npm test` runs Vitest 5 factory/unit tests. `npm run test:browser` runs Playwright
Chromium against an actual Go Web server with auth, embedded Alpine/htmx, job
workers and SSE. Install its browser with `npx playwright install chromium`;
Linux CI images may need `npx playwright install --with-deps chromium`.

The runner builds `pkg/web` as a test binary and starts only `TestBrowserFixture`
in a temporary home/config tree. Synthetic workers are controlled through stdin,
with no fixture HTTP route or production build hook. It exercises lifecycle
mount/removal, cancellation, failure, reconnect reconciliation, retained output,
deep-link history and primary route layouts. Browser reports and traces are
ignored artifacts under `playwright-report/` and `test-results/`.

For native remote QA, cross-build that test binary and set
`MPV_MANAGER_BROWSER_FIXTURE_BIN` to its absolute native path before running the
same browser suite. Run the final application and updater qualifier separately:
fixture coverage does not prove live signing, UAC interaction, antivirus/quarantine,
package-manager permissions or published-artifact behavior.

Run a built v1.3 application separately with
`node tests/browser/application-smoke.mjs /absolute/path/to/mpv-manager` (use the
`.exe` path on Windows). This checks native platform detection, version/help,
all primary routes at two widths, unauthenticated API rejection, and graceful
exit 0 after authenticated shutdown. It creates a disposable home/config tree.

### Windows default install regression

Run on Windows with native Chromium installed:

```powershell
node tests/browser/application-smoke.mjs C:/path/to/mpv-manager.exe 1.3.0-rc.9 --install-default-mpv --reinstall-mpv
```

The script uses a disposable home, retains the default destination, clicks the
Web install button and ModernZ confirmation, waits for the real job, verifies
mpv launches, and checks that existing config files and coordination locks
survive. The executable must match available signed release metadata. The
explicit-path CLI smoke does not cover this startup/default-path interaction.

All Windows mutation options (`--install-default-mpv`, `--reinstall-mpv`,
`--setup-default-app`) require a disposable `MPVRocksQA*` account: Windows
registry discovery can find real installations despite HOME/APPDATA overrides.
`--setup-default-app` runs mpv's native registrar, which writes to real registry
and Windows Known Folders locations. Run that browser option only under a
**disposable Windows account**, not merely a redirected HOME/APPDATA directory.
The native `TestNativeMPVRegistrarInDisposableAccount` requires a standard
`MPVRocksQA*` account and `MPV_MANAGER_QA_NATIVE_MPV` pointing to a reviewed mpv
binary in its disposable installation. It exercises real registration/removal,
legacy RC3–RC5 migration, incomplete-registration rejection and preservation of
another installation's active registration. Default-app chooser visibility must
also be checked in the actual Windows UI; a successful Settings launch alone is
not sufficient. `tests/browser/rc3-settings.spec.mjs`
covers progress-toast requests and switch keyboard/persistence/reset/failure paths
against the embedded frontend and real HTTP handlers.

The Windows application smoke seeds a legacy `mpc-qt-setup.exe` beside startup
locks and user config. `--reinstall-mpv` exercises actual Web install, uninstall
and reinstall in the same disposable default directory, checks both MPV launches,
and verifies the legacy setup is removed while user files survive unclaimed.
Native migration tests exercise existing managed installs, partial downloads,
pre-commit cancellation, locked files and directory/link preservation. Native installer
tests cover MPC-QT staging cleanup on success, download/checksum failures, commit
cancellation, installer failure and missing installed executable.

### Windows UX regressions (RC7–RC9)

`tests/browser/windows-ux-regressions.spec.mjs` exercises the embedded dialog
controller, Alpine, HTTP handlers and SSE in Chromium: Cancel/Escape focus
restoration, cancellation toast cleanup live and after reconnect, retry without
duplicate progress actions, and accessible job-modal button names. Native
`TestWindowsUninstallPreflightPreservesFilesAndShortcuts` checks a mapped running
executable, a locked support file and a read-only file. Each refusal must preserve
all owned bytes and shortcut sentinels; releasing the blocker permits preflight.
Job-manager tests reserve 100% for successful completion.

The owner has explicitly designated `agent` on `win-dev` for agent QA. Visible
desktop QA may use that account and its managed test installation after saving
configuration and state snapshots. The generic smoke runner's disposable-account
guard remains in place. Redirecting HOME/APPDATA still does not isolate registry
or Known Folders.

The fast-completion browser regression holds the start response until a real SSE
error is delivered and retired, then verifies the Uninstall button recovers using
the retained HTTP job result. This covers completion before callback registration.

`tests/browser/job-navigation.spec.mjs` uses full Chromium with back/forward
caching enabled; the default headless shell disables that cache. It checks one
server SSE client across navigation and cached Back restoration, and reconciles
a job that completed while its original page was cached. The stdin-only fixture
client count is absent from production builds and HTTP routes.

## Operation and persistence regressions

The maintained tests now include actual Bubble Tea program exit and subprocess
SIGTERM draining, CLI update HTTP cancellation, native Windows held-handle locator
publication and recovery, repeated macOS framework-link recovery with metadata
preservation, unsafe-link refusal, and native ICNS dimensions. Windows tests cover
pre-commit UI failure, two managed/adopted installations with different UIs,
actual `.lnk` targets in temporary Desktop/Start Menu directories, and preservation
of an installed manager sentinel during ordinary TUI startup.

The Chromium `ui-migration.spec.mjs` tests delay real HTTP requests to prove that
an earlier save precedes a migration and that later edits/resets remain authoritative.
`pkg/uiconfig` also checks rejection of intervening external edits.

Config and installer fixtures redirect HOME, USERPROFILE, APPDATA, LOCALAPPDATA,
and XDG_CONFIG_HOME as appropriate and restore their environment. Run native
binaries inside an additional disposable profile; cross-compilation is not a
substitute for the native filesystem/COM/framework checks.

The production/test-root reachability inventory is an audit aid. Preserve useful
injection seams and supported exports; tests of a removed compatibility wrapper
should be replaced by coverage of a shipped behavior, not kept solely to make the
wrapper appear reachable. Package-local installer doubles belong in `_test.go`.

## Native installer regressions

Mac bundle discovery must not execute discovered player code. Windows
method-collection coverage checks that another destination remains installable.
New builds reject older signed metadata, so final network QA requires a freshly
reviewed and signed candidate.

`TestMacDeniedBundleInstallPreservesConfiguration` runs as a standard macOS
account without `/Applications` write access. Its downloaded bundle is a
controlled fixture; extraction, permission refusal, configuration preservation
and staging cleanup are real. It skips accounts able to write the destination.

`TestMacBundleInstallPreservesExistingConfig` is opt-in through
`MPV_QA_DISPOSABLE_APPLICATIONS=1` on a Mac explicitly dedicated to destructive
application QA. It refuses any existing `/Applications/MPV.app`, installs a
controlled fixture through the real native transaction, and cleans up only
its identifiable fixture bundle. It covers fresh defaults and existing config
bytes/permissions. Standard test runs skip it. Existing apps must be moved to
a retained QA baseline or removed through an authorized application workflow
before opting in.

`TestShutdownDrainsUnusedBrowserConnection` holds an accepted TCP connection
without sending a request. The shutdown deadline must allow Go's five-second
new-connection grace period and polling overhead. Persistent SSE streams and
committed workers have separate drain regressions.

Explicit update checks on Dashboard and Apps fetch a newly authenticated manifest
with request cancellation before recalculating versions. Browser acceptance
checks that a release appearing after startup updates the manager status and
install choices without restarting, and that fetch/signature errors are visible
while retaining the last accepted snapshot. Automatic post-job list refreshes
reuse their existing manifest and do not initiate unrelated network checks.

Passwordless sudo acceptance includes sudo-rs: its validation-only `-v` can
require a password despite NOPASSWD command authorization. The harmless absolute
`/usr/bin/true` probe checks actual noninteractive command permission; subsequent
package operations still use `sudo -n` and report any narrower policy refusal.

### uOSC release-layout regression

`TestUOSCArchiveLayout` and the UI transaction tests cover the directory entry
point, icon/texture fonts, unrelated-path rejection, rollback, and UI removal.
For native QA, download the pinned uOSC 5.13.0 archive and set
`MPV_MANAGER_QA_UOSC_ARCHIVE` to its local path before running
`go test ./pkg/installer -run TestUOSCReleasedArchive -v`. The test verifies its
reviewed BLAKE3 digest before exercising install, update with custom settings,
and removal while retaining an unrelated font. Ordinary tests stay offline.

The browser association regression renders two real Windows app cards and checks
that setup/removal retain each installation's ID after card replacement. Native
acceptance must additionally inspect the registry and Windows Default apps, and
exercise default/custom MPV locations and uOSC/ModernZ/default UI switching.
`TestNativeShortcutFailureReturnsWithoutDialog` checks a real script-host failure
returns promptly; `TestNativeShortcutUsesSelectedApp` checks missing shortcut
folders are created and the resulting `.lnk` files target the selected app.

## October 2026 audit regressions

The audit remediation adds failure-outcome checks for authenticated installer
intent and exact destination binding, unavailable keys, private journal DACLs in
shared Windows parents, untouched FFmpeg scratch collisions, bounded Flatpak
remote probes before commit, matching ARM64/AMD64 PE validation, and tar header
budget/cancellation ordering. Windows atomic replacement retains the original
owner and DACL; private backup files do not inherit Everyone read access.

Updater tests cover replay after a restoration consumed its backup, authenticated
live-original validation before execution, finalized-journal cleanup after manual
replacement, and retaining evidence when outcome publication fails. ModernZ
migration recovery refuses to overwrite later edits and recognizes an already
restored snapshot. Hotkey tests preserve quoted whitespace, BOM/newlines and
private modes during unrelated edits. Config form/browser tests retain custom
values and distinguish omitted fields from explicit clears.

The real-browser suite also holds job-details responses across terminal SSE
success/error/cancellation, closes dialogs during pending reads, switches job
selection, observes delayed adoption through completion, starts work in a second
tab after Tasks goes idle, and checks actual Alpine listener cleanup. These tests
exercise shipped templates, framework lifecycle, HTTP handlers and EventSource.
Frontend factory tests remain a focused supplement.

Native mount/recovery checks must run on macOS in disposable paths:

```bash
MPV_MANAGER_NATIVE_DMG_QA=1 go test ./pkg/installer \
  -run '^TestNative(InterruptedDMGAttachDetachesOwnedMount|InstallerRecoveryInApplications)$' \
  -v -count=1
```

These tests create their own empty disk image and temporary files; they do not
replace installed player bundles. On Windows, run
`TestWindowsAtomicWritePreservesPrivateDACLInSharedParent` in `internal/fileops`,
`TestInstallerJournalPrivateInInheritedReadableWindowsParent` and
`TestWindowsWebShortcutPreservesInstalledManager` in `pkg/installer` under the
dedicated `agent` account. Cross-compiling them is not a native pass.

Long-session logger tests verify rotation at 10 MiB, one retained backup,
flush/clear behavior, oversized record bounds and retry after a failed reopen.
Native Windows clear-after-rotation checks verify a write-capable truncation
handle still identifies the writer's owned file and that later append records
and the retained archive survive repeated clears. Portable subprocess fixtures
exercise stdout, stderr, exit codes, timeout and cancellation on each OS; the
retained shell API additionally checks native quoting and stop-on-failure.
The job-summary benchmark compares metadata snapshots with full detail snapshots;
keep output-tail retention and coherent active/recent state as correctness gates.
