Skip to content

fix(release-verify): bound guest campaign watching and never fall back to a credential prompt - #425

Merged
Exoridus merged 1 commit into
nextfrom
fix/vm-bounded-guest-watch
Sep 25, 2026
Merged

Exoridus merged 1 commit into
nextfrom
fix/vm-bounded-guest-watch

Conversation

@Exoridus

Copy link
Copy Markdown
Owner

Why

Following an operator-gated guest campaign from the host had no supported path. An ad hoc poll loop ran powershell.exe against tools/vm/ReleaseVm.psm1. The execution policy stops Windows PowerShell from loading the module, so New-ReleaseVmCredential never existed and the credential was $null. Invoke-Command -Credential $null then opened an interactive "Sign in to PowerShell" dialog on the host desktop every poll, the loop never ended, and the terminal had to be force-closed.

What changes

  • tools/vm/Watch-ReleaseVmRun.ps1 follows a running guest campaign. It is read-only, never prompts (no mandatory parameters, so a missing argument is an error instead of a question), and every way out is bounded:
    • each PowerShell Direct read runs as a job with its own timeout;
    • consecutive failed reads end the watch as unreachable (exit 3);
    • -TimeoutMinutes ends it regardless of the guest (exit 2);
    • exit 0 means the guest exit file appeared. Its content is printed, not propagated.
    • The process ends through [Environment]::Exit, because disposing an abandoned PowerShell Direct runspace blocks as long as the guest does not answer.
  • Read-ReleaseVmGuestProgress returns only complete UTF-8 log lines from a byte offset, plus the exit-file state. Its guest side stays Windows PowerShell 5.1 compatible.
  • Watch-ReleaseVmGuestRun holds the loop with injectable read, clock and sleep, so the deadline and failure bounds are unit-tested.
  • docs/dev/release-verify-vm.md documents the watch and the powershell.exe credential trap.

Evidence

  • scripts/tests/vm-recipe.tests.ps1: 142 passed, 0 failed. The new cases cover ordered log output and offsets, the deadline when an operator gate is never answered, the unreachable bound and its reset, refusal of a $null credential instead of a prompt, and the script refusing a missing argument without asking.
  • Live, against a running disposable guest with an operator-gated update.msi-decline-real campaign:
    • a 1-minute watch printed the campaign transcript and ended with exit 2 while the campaign kept running;
    • a 45-minute watch then followed the gate to completion and ended with exit 0 after the operator declined the real UAC prompt. The scenario verdict was PASS.
  • Pre-commit verify.ps1 -Fast passed.
  • PSScriptAnalyzer is not installed locally and was not run.

@Exoridus
Exoridus marked this pull request as ready for review September 25, 2026 05:52
@Exoridus
Exoridus merged commit 1a7ed8e into next Sep 25, 2026
13 checks passed
@Exoridus
Exoridus deleted the fix/vm-bounded-guest-watch branch September 25, 2026 06:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant