Add XR interactive desktop bridge proof

This commit is contained in:
axiomlogicnexus 2026-07-02 08:02:11 +00:00
parent eff75c3cfa
commit da911b07fb
10 changed files with 454 additions and 5 deletions

View file

@ -0,0 +1,31 @@
{
"reportVersion": "ht-interactive-desktop-task/v1",
"generatedAtUtc": "2026-07-02T07:55:45.0811556Z",
"taskName": "HyperTwist-InteractiveDesktop-20260702-095545",
"taskRunnerPath": "C:\\Windows\\Temp\\HyperTwist-InteractiveDesktop-20260702-095545.runner.ps1",
"taskResultPath": "C:\\Windows\\Temp\\HyperTwist-InteractiveDesktop-20260702-095545.result.json",
"timeoutSeconds": 210,
"currentSessionId": 0,
"explorerSessionIds": [
1
],
"createExitCode": 0,
"runExitCode": 0,
"taskOutput": {
"succeeded": true,
"user": "DESKTOP-KS3VGHU\\Anthracite Ace",
"processId": 15760,
"sessionId": 1,
"explorerSessionIds": [
1
],
"generatedAtUtc": "2026-07-02T07:55:55.5084184Z",
"outputLines": [
"XR_WINDOWED_EXPECTED_ERROR=Windowed XR validation requires an installed active OpenXR runtime, but no OpenXR ActiveRuntime registry entry was found. Activate SteamVR, Oculus, Windows Mixed Reality, or another local OpenXR runtime on the interactive desktop and rerun.",
"{\r\n \"reportVersion\": \"ht-xr-windowed-live-observation/v1\",\r\n \"generatedAtUtc\": \"2026-07-02T07:55:55.6890920Z\",\r\n \"packageRoot\": \"C:\\\\HyperTwist_worktrees\\\\phase10validate_packaged_xr_20260702_rebuild\",\r\n \"smokeMaps\": [\r\n \"/Game/HyperTwistTraining/Maps/L_HyperTwist_FollowAlongTraining\",\r\n \"/Game/HyperTwistTraining/Maps/L_HyperTwist_ClassicTraining\"\r\n ],\r\n \"observationSeconds\": 120,\r\n \"timeoutSeconds\": 150,\r\n \"runtimeLaunchMode\": \"windowed\",\r\n \"resolution\": {\r\n \"width\": 1600,\r\n \"height\": 900\r\n },\r\n \"smokeReports\": [\r\n {\r\n \"reportVersion\": \"ht-xr-package-smoke/v1\",\r\n \"generatedAtUtc\": \"2026-07-02T07:55:55.8312741Z\",\r\n \"packageRoot\": \"C:\\\\HyperTwist_worktrees\\\\phase10validate_packaged_xr_20260702_rebuild\",\r\n \"executablePath\": \"C:\\\\HyperTwist_worktrees\\\\phase10validate_packaged_xr_20260702_rebuild\\\\Windows\\\\UnrealHyperTwist.exe\",\r\n \"mapAssetPath\": \"/Game/HyperTwistTraining/Maps/L_HyperTwist_FollowAlongTraining\",\r\n \"mapUrl\": \"/Game/HyperTwistTraining/Maps/L_HyperTwist_FollowAlongTraining?game=/Script/UnrealHyperTwist.HyperTwistXrTrainingGameMode\",\r\n \"runtimeLaunchMode\": \"windowed\",\r\n \"observationSeconds\": 120,\r\n \"timeoutSeconds\": 150,\r\n \"resolution\": {\r\n \"width\": 1600,\r\n \"height\": 900\r\n },\r\n \"keepRunning\": false,\r\n \"runtimeReportPath\": \"C:\\\\HyperTwist_worktrees\\\\phase10validate_packaged_xr_20260702_rebuild\\\\validation\\\\windowed-live-interactive-probe\\\\_Game_HyperTwistTraining_Maps_L_HyperTwist_FollowAlongTraining.runtime.json\",\r\n \"preflight\": {\r\n \"currentSessionId\": 1,\r\n \"explorerSessionIds\": [\r\n 1\r\n ],\r\n \"isInteractiveDesktopSession\": true,\r\n \"openXrActiveRuntimePath\": null,\r\n \"openXrActiveRuntimePresent\": false\r\n },\r\n \"result\": \"failed\",\r\n \"processId\": null,\r\n \"processStopped\": false,\r\n \"exitCode\": null,\r\n \"runtimeReport\": null,\r\n \"error\": \"Windowed XR validation requires an installed active OpenXR runtime, but no OpenXR ActiveRuntime registry entry was found. Activate SteamVR, Oculus, Windows Mixed Reality, or another local OpenXR runtime on the interactive desktop and rerun.\"\r\n }\r\n ],\r\n \"preflight\": {\r\n \"currentSessionId\": 1,\r\n \"explorerSessionIds\": [\r\n 1\r\n ],\r\n \"isInteractiveDesktopSession\": true,\r\n \"openXrActiveRuntimePath\": null,\r\n \"openXrActiveRuntimePresent\": false\r\n },\r\n \"packagedHeadMountedDisplaySessionObserved\": false,\r\n \"packagedControllerInputObserved\": false,\r\n \"remainingGateIds\": [\r\n\r\n ],\r\n \"result\": \"failed\",\r\n \"error\": \"Windowed XR validation requires an installed active OpenXR runtime, but no OpenXR ActiveRuntime registry entry was found. Activate SteamVR, Oculus, Windows Mixed Reality, or another local OpenXR runtime on the interactive desktop and rerun.\"\r\n}"
],
"error": null
},
"result": "passed",
"error": null
}

View file

@ -0,0 +1,66 @@
{
"reportVersion": "ht-xr-windowed-live-observation/v1",
"generatedAtUtc": "2026-07-02T07:55:55.6890920Z",
"packageRoot": "C:\\HyperTwist_worktrees\\phase10validate_packaged_xr_20260702_rebuild",
"smokeMaps": [
"/Game/HyperTwistTraining/Maps/L_HyperTwist_FollowAlongTraining",
"/Game/HyperTwistTraining/Maps/L_HyperTwist_ClassicTraining"
],
"observationSeconds": 120,
"timeoutSeconds": 150,
"runtimeLaunchMode": "windowed",
"resolution": {
"width": 1600,
"height": 900
},
"smokeReports": [
{
"reportVersion": "ht-xr-package-smoke/v1",
"generatedAtUtc": "2026-07-02T07:55:55.8312741Z",
"packageRoot": "C:\\HyperTwist_worktrees\\phase10validate_packaged_xr_20260702_rebuild",
"executablePath": "C:\\HyperTwist_worktrees\\phase10validate_packaged_xr_20260702_rebuild\\Windows\\UnrealHyperTwist.exe",
"mapAssetPath": "/Game/HyperTwistTraining/Maps/L_HyperTwist_FollowAlongTraining",
"mapUrl": "/Game/HyperTwistTraining/Maps/L_HyperTwist_FollowAlongTraining?game=/Script/UnrealHyperTwist.HyperTwistXrTrainingGameMode",
"runtimeLaunchMode": "windowed",
"observationSeconds": 120,
"timeoutSeconds": 150,
"resolution": {
"width": 1600,
"height": 900
},
"keepRunning": false,
"runtimeReportPath": "C:\\HyperTwist_worktrees\\phase10validate_packaged_xr_20260702_rebuild\\validation\\windowed-live-interactive-probe\\_Game_HyperTwistTraining_Maps_L_HyperTwist_FollowAlongTraining.runtime.json",
"preflight": {
"currentSessionId": 1,
"explorerSessionIds": [
1
],
"isInteractiveDesktopSession": true,
"openXrActiveRuntimePath": null,
"openXrActiveRuntimePresent": false
},
"result": "failed",
"processId": null,
"processStopped": false,
"exitCode": null,
"runtimeReport": null,
"error": "Windowed XR validation requires an installed active OpenXR runtime, but no OpenXR ActiveRuntime registry entry was found. Activate SteamVR, Oculus, Windows Mixed Reality, or another local OpenXR runtime on the interactive desktop and rerun."
}
],
"preflight": {
"currentSessionId": 1,
"explorerSessionIds": [
1
],
"isInteractiveDesktopSession": true,
"openXrActiveRuntimePath": null,
"openXrActiveRuntimePresent": false
},
"packagedHeadMountedDisplaySessionObserved": false,
"packagedControllerInputObserved": false,
"remainingGateIds": [
],
"result": "failed",
"error": "Windowed XR validation requires an installed active OpenXR runtime, but no OpenXR ActiveRuntime registry entry was found. Activate SteamVR, Oculus, Windows Mixed Reality, or another local OpenXR runtime on the interactive desktop and rerun."
}

View file

@ -243,3 +243,15 @@ widening.
1. activate a real local `OpenXR` runtime on the Windows desktop
2. run the first-party windowed observation wrapper from that interactive
desktop session rather than through the reverse-SSH/OpenSSH session
- the next same-day bridge continuation then tightened that host reading again:
- the repo now also carries
`scripts\Invoke-HyperTwistInteractiveDesktopTask.ps1`
- checked-in bridge proof
`docs/generated/xr/xr_interactive_desktop_task_probe_2026-07-02.json`
now proves the reverse-SSH Session `0` lane can launch a bounded first-
party task into the real Explorer desktop Session `1`
- the XR lane then reran through that bridge and checked in
`docs/generated/xr/xr_windowed_interactive_desktop_probe_2026-07-02.json`
- that rerun shows the interactive-desktop requirement is now satisfied and
the remaining blocker has narrowed further to one host fact only:
`OpenXR` still has no active runtime registered on the desktop

View file

@ -750,14 +750,44 @@ Operational rules reinforced by this proof:
- the reverse-SSH lane is **not** the authoritative live windowed XR proof
lane while it is entering Session `0` rather than the interactive desktop
Session `1`
- the remaining headset/controller observation gate must be run locally on
the logged-in Windows desktop after an `OpenXR` runtime is actually active
- canonical local Windows desktop command for that remaining gate:
- that left the remaining headset/controller observation gate temporarily
blocked on the interactive-desktop launch context
- the next same-day continuation then closed that launch-context gap without
widening beyond the XR proof lane:
- the repo now also carries
`scripts\Invoke-HyperTwistInteractiveDesktopTask.ps1`
- checked-in bridge proof:
`docs/generated/xr/xr_interactive_desktop_task_probe_2026-07-02.json`
- that bridge proof shows:
- scheduler task creation from Session `0`: passed
- scheduler task run from Session `0`: passed
- resulting task session id: `1`
- resulting task explorer-session parity: `1`
- a later same-day XR rerun through that new bridge then produced:
`docs/generated/xr/xr_windowed_interactive_desktop_probe_2026-07-02.json`
with:
- `currentSessionId: 1`
- `isInteractiveDesktopSession: true`
- `openXrActiveRuntimePresent: false`
- error narrowed to missing active `OpenXR` runtime
- operational reading after the bridge continuation:
- the reverse-SSH lane plus first-party interactive-desktop task bridge can
now initiate the real Session `1` windowed XR proof path
- the remaining blocker is no longer the desktop-session bridge
- the remaining blocker is the absent active `OpenXR` runtime on the logged-
in Windows desktop
- canonical local Windows desktop command for that remaining gate is still:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File C:\HyperTwist_worktrees\phase10validate\scripts\Invoke-HyperTwistXrWindowedObservation.ps1 -PackageRoot C:\HyperTwist_worktrees\phase10validate_packaged_xr_20260702_rebuild
```
- canonical Session `0` bridge-assisted command shape is now:
```powershell
& 'C:\HyperTwist_worktrees\phase10validate\scripts\Invoke-HyperTwistInteractiveDesktopTask.ps1' -InlineCommand "& 'C:\HyperTwist_worktrees\phase10validate\scripts\Invoke-HyperTwistXrWindowedObservation.ps1' -PackageRoot 'C:\HyperTwist_worktrees\phase10validate_packaged_xr_20260702_rebuild'"
```
- that local desktop run writes the aggregate live-observation report beneath:
`C:\HyperTwist_worktrees\phase10validate_packaged_xr_20260702_rebuild\validation\windowed-live\`

View file

@ -631,3 +631,17 @@ But the mature path is:
- skills second
- clean-room command specs for restrictive lanes
- no donor command surface promoted into product truth by accident
## Update - 2026-07-02 - reverse-SSH interactive desktop bridge wrapper
- the current repo-local wrapper family now also includes a bounded first-party
Windows-side interactive-desktop bridge command surface:
`scripts\Invoke-HyperTwistInteractiveDesktopTask.ps1`
- this wrapper does not create a new product feature by itself
- it exists so a Session `0` reverse-SSH operator lane can trigger a bounded
first-party task inside the real logged-in Windows desktop Session `1`,
collect structured JSON output, and keep the bridge truth source-controlled
- current checked-in proof for that wrapper is:
`docs/generated/xr/xr_interactive_desktop_task_probe_2026-07-02.json`
- the wrapper therefore belongs to the bounded workflow/review or provider/ops
command-surface family, not to the shippable gameplay feature layer

View file

@ -411,6 +411,17 @@ scripts/run-hypertwist-remote-unreal-automation-sequence.sh \
`scripts\Invoke-HyperTwistXrWindowedObservation.ps1` exists specifically so
that gate can fail fast with preflight evidence when the launcher is not on
the interactive desktop or when no `OpenXR` active runtime is present
- later same-day `2026-07-02` continuation proof then added
`scripts\Invoke-HyperTwistInteractiveDesktopTask.ps1`, which lets the
reverse-SSH Session `0` lane trigger a bounded first-party task inside the
logged-in Explorer desktop Session `1`; checked-in proof now lives at
`docs/generated/xr/xr_interactive_desktop_task_probe_2026-07-02.json`
- after that bridge landed, the remaining live packaged XR blocker narrowed
again: current checked-in rerun
`docs/generated/xr/xr_windowed_interactive_desktop_probe_2026-07-02.json`
proves the session-context requirement is satisfied and that the only
remaining blocker is an absent active `OpenXR` runtime on the Windows
desktop
- for reverse-SSH/headless classic-cube replay-export validation, use
`-NullRHI` only for the asset-authoring leg and `-RenderOffScreen` for the
actual `MovieRenderQueue` render leg; they solve different failure modes

View file

@ -418,6 +418,18 @@ truthfully claim:
interactive Explorer desktop is Session `1`
- that same probe also keeps the local runtime blocker explicit by recording
that no `OpenXR` active runtime is currently registered on the host
- a later same-day bridge continuation then removed the session-context part of
that blocker:
- the repo now also carries
`scripts\Invoke-HyperTwistInteractiveDesktopTask.ps1`
- checked-in bridge proof:
`docs/generated/xr/xr_interactive_desktop_task_probe_2026-07-02.json`
- checked-in bridged XR rerun:
`docs/generated/xr/xr_windowed_interactive_desktop_probe_2026-07-02.json`
- that bridged rerun proves the remaining live XR lane can now be launched in
Session `1` with `isInteractiveDesktopSession: true`
- the remaining blocker is therefore narrowed to absent active `OpenXR`
runtime, not to the Windows desktop-session bridge anymore
- the current remaining unproven pieces therefore are:
- live packaged headset-session observation on the Windows lane
- live packaged controller-input observation on the Windows lane
@ -500,5 +512,7 @@ first clean remaining implementation packet should be:
owner plus controller settings/rebinding substrate and above the already-
shipped headless `nullrhi` packaged structural proof, and run from the
interactive logged-in Windows desktop session with an active local `OpenXR`
runtime rather than from the reverse-SSH/OpenSSH Session `0` lane
runtime; that session may now be reached either directly on the desktop or
through the new first-party interactive-desktop task bridge above the
reverse-SSH Session `0` lane
2. public/product copy update only after that live packaged proof exists

View file

@ -2502,6 +2502,44 @@ Latest same-family responsive public-route expansion follow-up on `2026-06-29`:
powershell -NoProfile -ExecutionPolicy Bypass -File C:\HyperTwist_worktrees\phase10validate\scripts\Invoke-HyperTwistXrWindowedObservation.ps1 -PackageRoot C:\HyperTwist_worktrees\phase10validate_packaged_xr_20260702_rebuild
```
## XR interactive desktop bridge continuation (`2026-07-02`)
- the next same-family continuation then closed the remaining Session `0`
versus Session `1` launcher gap instead of leaving the final XR gate as
manual-desktop-only lore
- current exact-source truth is now source-backed through:
- `scripts/Invoke-HyperTwistInteractiveDesktopTask.ps1`
- checked-in bridge proof:
`docs/generated/xr/xr_interactive_desktop_task_probe_2026-07-02.json`
- checked-in bridged XR rerun:
`docs/generated/xr/xr_windowed_interactive_desktop_probe_2026-07-02.json`
- the new helper now lets the reverse-SSH Session `0` lane create and run a
bounded `INTERACTIVE` scheduled task on the same logged-in Windows desktop,
then wait for a structured JSON result instead of leaving that desktop hop to
manual operator timing
- the helper proof established:
- launcher session before bridge: `0`
- Explorer desktop session: `1`
- scheduled task creation: passed
- scheduled task run: passed
- resulting bridged task session: `1`
- the XR windowed observation wrapper was then rerun through that bridged
Session `1` path and the current remaining blocker narrowed again:
- `isInteractiveDesktopSession: true`
- `openXrActiveRuntimePresent: false`
- failure reason now points only to the missing active `OpenXR` runtime
- current truthful reading after this continuation:
- HyperTwist now owns a first-party reverse-SSH-to-desktop bridge for the
remaining live XR observation lane
- the session-context blocker is closed
- the remaining live XR blocker is the absent active `OpenXR` runtime on the
logged-in Windows desktop
- canonical bridged command shape from Session `0` is now:
```powershell
& 'C:\HyperTwist_worktrees\phase10validate\scripts\Invoke-HyperTwistInteractiveDesktopTask.ps1' -InlineCommand "& 'C:\HyperTwist_worktrees\phase10validate\scripts\Invoke-HyperTwistXrWindowedObservation.ps1' -PackageRoot 'C:\HyperTwist_worktrees\phase10validate_packaged_xr_20260702_rebuild'"
```
## Latest protected launch-status responsive recovery plus tooling rerun (`2026-06-29`)
- the next same-family browser pass fixed a real small-screen regression on the

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,233 @@
param(
[Parameter(Mandatory = $true)]
[string]$InlineCommand,
[int]$TimeoutSeconds = 120,
[string]$TaskNamePrefix = 'HyperTwist-InteractiveDesktop',
[string]$ResultPath = '',
[switch]$KeepArtifacts
)
$ErrorActionPreference = 'Stop'
function Write-Utf8JsonFile {
param(
[Parameter(Mandatory = $true)]
[string]$Path,
[Parameter(Mandatory = $true)]
[object]$Value
)
$ParentPath = Split-Path -Parent $Path
if (-not [string]::IsNullOrWhiteSpace($ParentPath))
{
New-Item -ItemType Directory -Force -Path $ParentPath | Out-Null
}
$Json = $Value | ConvertTo-Json -Depth 12
$Utf8NoBom = New-Object System.Text.UTF8Encoding($false)
[System.IO.File]::WriteAllText($Path, $Json, $Utf8NoBom)
}
function Read-JsonFile {
param(
[Parameter(Mandatory = $true)]
[string]$Path
)
return Get-Content -LiteralPath $Path -Raw | ConvertFrom-Json
}
function Convert-TaskToken {
param(
[string]$Value
)
if ([string]::IsNullOrWhiteSpace($Value))
{
return 'unknown'
}
return ($Value -replace '[^A-Za-z0-9_-]', '_')
}
if ([string]::IsNullOrWhiteSpace($InlineCommand))
{
throw 'Provide -InlineCommand.'
}
$TaskToken = Convert-TaskToken -Value (
'{0}-{1}' -f $TaskNamePrefix, (Get-Date).ToString('yyyyMMdd-HHmmss')
)
$TaskName = $TaskToken
$TaskRunnerPath = 'C:\Windows\Temp\{0}.runner.ps1' -f $TaskToken
$TaskResultPath = 'C:\Windows\Temp\{0}.result.json' -f $TaskToken
$EncodedInlineCommand = [Convert]::ToBase64String(
[System.Text.Encoding]::Unicode.GetBytes($InlineCommand)
)
if (Test-Path -LiteralPath $TaskResultPath)
{
Remove-Item -LiteralPath $TaskResultPath -Force
}
$RunnerScript = @"
`$ErrorActionPreference = 'Stop'
`$Result = [ordered]@{
succeeded = `$false
user = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
processId = `$PID
sessionId = (Get-Process -Id `$PID).SessionId
explorerSessionIds = @((Get-Process explorer -ErrorAction SilentlyContinue | Select-Object -ExpandProperty SessionId -Unique))
generatedAtUtc = [DateTime]::UtcNow.ToString('o')
outputLines = @()
error = `$null
}
try {
`$CommandSource = [System.Text.Encoding]::Unicode.GetString(
[Convert]::FromBase64String('$EncodedInlineCommand')
)
`$CapturedOutput = @(& ([scriptblock]::Create(`$CommandSource)) 2>&1 | ForEach-Object { `$_.ToString() })
`$Result.outputLines = @(`$CapturedOutput)
`$Result.succeeded = `$true
} catch {
if (`$null -ne `$CapturedOutput) {
`$Result.outputLines = @(`$CapturedOutput)
}
`$Result.error = `$_.Exception.Message
}
[System.IO.File]::WriteAllText(
'$TaskResultPath',
(`$Result | ConvertTo-Json -Depth 12),
(New-Object System.Text.UTF8Encoding(`$false))
)
if (-not `$Result.succeeded) {
exit 1
}
"@
[System.IO.File]::WriteAllText(
$TaskRunnerPath,
$RunnerScript,
(New-Object System.Text.UTF8Encoding($false))
)
$Result = [ordered]@{
reportVersion = 'ht-interactive-desktop-task/v1'
generatedAtUtc = [DateTime]::UtcNow.ToString('o')
taskName = $TaskName
taskRunnerPath = $TaskRunnerPath
taskResultPath = $TaskResultPath
timeoutSeconds = $TimeoutSeconds
currentSessionId = (Get-Process -Id $PID).SessionId
explorerSessionIds = @(
Get-Process explorer -ErrorAction SilentlyContinue |
Select-Object -ExpandProperty SessionId -Unique
)
createExitCode = $null
runExitCode = $null
taskOutput = $null
result = 'failed'
error = $null
}
try
{
$CreateArgs = @(
'/Create', '/F',
'/TN', $TaskName,
'/SC', 'ONCE',
'/ST', '23:59',
'/SD', (Get-Date).ToString('MM/dd/yyyy'),
'/TR', ('C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -ExecutionPolicy Bypass -File {0}' -f $TaskRunnerPath),
'/RU', 'INTERACTIVE'
)
& schtasks.exe @CreateArgs | Out-Null
$Result.createExitCode = $LASTEXITCODE
if ($Result.createExitCode -ne 0)
{
throw "Creating the interactive desktop task failed with exit code $($Result.createExitCode)."
}
& schtasks.exe /Run /TN ('\' + $TaskName) | Out-Null
$Result.runExitCode = $LASTEXITCODE
if ($Result.runExitCode -ne 0)
{
throw "Running the interactive desktop task failed with exit code $($Result.runExitCode)."
}
$Deadline = [DateTime]::UtcNow.AddSeconds([Math]::Max($TimeoutSeconds, 1))
while ([DateTime]::UtcNow -lt $Deadline)
{
if (Test-Path -LiteralPath $TaskResultPath)
{
break
}
Start-Sleep -Milliseconds 500
}
if (-not (Test-Path -LiteralPath $TaskResultPath))
{
throw "The interactive desktop task did not write '$TaskResultPath' before timeout."
}
$TaskOutput = Read-JsonFile -Path $TaskResultPath
if ($null -eq $TaskOutput)
{
throw "The interactive desktop task result '$TaskResultPath' could not be parsed."
}
$Result.taskOutput = $TaskOutput
if (-not [bool]$TaskOutput.succeeded)
{
$TaskError = if ([string]::IsNullOrWhiteSpace([string]$TaskOutput.error))
{
'The interactive desktop task reported failure without an explicit error message.'
}
else
{
[string]$TaskOutput.error
}
throw $TaskError
}
$Result.result = 'passed'
}
catch
{
$Result.error = $_.Exception.Message
if ($null -eq $Result.taskOutput -and (Test-Path -LiteralPath $TaskResultPath))
{
$Result.taskOutput = Read-JsonFile -Path $TaskResultPath
}
$ResolvedFailureResultPath = if ([string]::IsNullOrWhiteSpace($ResultPath))
{
$TaskResultPath
}
else
{
$ResultPath
}
Write-Utf8JsonFile -Path $ResolvedFailureResultPath -Value $Result
throw
}
finally
{
if (-not $KeepArtifacts)
{
& schtasks.exe /Delete /TN $TaskName /F | Out-Null
if (Test-Path -LiteralPath $TaskRunnerPath)
{
Remove-Item -LiteralPath $TaskRunnerPath -Force
}
}
}
if ([string]::IsNullOrWhiteSpace($ResultPath))
{
$ResultPath = $TaskResultPath
}
Write-Utf8JsonFile -Path $ResultPath -Value $Result
$Result | ConvertTo-Json -Depth 12