diff --git a/docs/muninn.md b/docs/muninn.md index c5a7dc3..17b647f 100644 --- a/docs/muninn.md +++ b/docs/muninn.md @@ -199,15 +199,17 @@ missing or the Quest is unavailable, Muninn publishes `muninn.quest_access` as Raven runs Muninn from `C:\Meta\Odin\Muninn`. `scripts/restart-muninn.ps1` recreates the `GameCult-Muninn` scheduled task with `wscript.exe` as the task -action and `start-muninn-serve-hidden.vbs` as its argument. The VBS launches -`start-muninn-serve.ps1` with noninteractive hidden PowerShell. The PowerShell -launcher starts `muninn.exe` with `-WindowStyle Hidden` and redirects logs under -`C:\Meta\Odin\logs\muninn`. +action and `start-muninn-serve-hidden.vbs` as its argument. It also repairs +`GameCult-Muninn-Activate` and `GameCult-Muninn-VideoProof` to execute their +hidden VBS launchers directly when those compatibility commands exist on Raven. +The serve VBS launches `start-muninn-serve.ps1` with noninteractive hidden +PowerShell. The PowerShell launcher starts `muninn.exe` with +`-WindowStyle Hidden` and redirects logs under `C:\Meta\Odin\logs\muninn`. Raven is an operator-consented host: Muninn operations on Raven must be background-only and must not create visible terminal windows. `.cmd` files may exist only as manual compatibility trampolines; Task Scheduler must execute hidden launchers directly and must not flash an interactive console on Raven. -The repair actuator for live Raven task drift is +The standalone repair actuator for live Raven task drift is `E:\Projects\Odin\scripts\repair-raven-muninn-task-actions.ps1`. It must register `GameCult-Muninn`, `GameCult-Muninn-Activate`, and `GameCult-Muninn-VideoProof` with `wscript.exe` as the task action and the diff --git a/scripts/restart-muninn.ps1 b/scripts/restart-muninn.ps1 index e6f0df9..4f106b5 100644 --- a/scripts/restart-muninn.ps1 +++ b/scripts/restart-muninn.ps1 @@ -24,6 +24,10 @@ New-Item -ItemType Directory -Force -Path (Split-Path -Parent "$StorePath") | Ou `$launcher = Join-Path `$muninnDir "start-muninn-serve.cmd" `$psLauncher = Join-Path `$muninnDir "start-muninn-serve.ps1" `$vbsLauncher = Join-Path `$muninnDir "start-muninn-serve-hidden.vbs" +`$activateCmd = Join-Path `$muninnDir "activate-raven-av-srt.cmd" +`$activateVbs = Join-Path `$muninnDir "activate-raven-av-srt-hidden.vbs" +`$videoProofCmd = Join-Path `$muninnDir "muninn-raven-video-to-starfire-obs.cmd" +`$videoProofVbs = Join-Path `$muninnDir "muninn-raven-video-to-starfire-obs-hidden.vbs" `$pidPath = Join-Path "$LogRoot" "muninn-serve.pid" `$psLines = @( '`$ErrorActionPreference = "Stop"', @@ -46,11 +50,75 @@ Set-Content -LiteralPath `$vbsLauncher -Value `$vbsLines -Encoding ASCII "wscript.exe //B //Nologo ""`$vbsLauncher""" ) Set-Content -LiteralPath `$launcher -Value `$lines -Encoding ASCII -`$taskAction = New-ScheduledTaskAction -Execute "wscript.exe" -Argument "//B //Nologo ""`$vbsLauncher""" -`$taskTrigger = New-ScheduledTaskTrigger -Once -At ([DateTime]::Today.AddHours(23).AddMinutes(59)) -`$taskPrincipal = New-ScheduledTaskPrincipal -UserId ([System.Security.Principal.WindowsIdentity]::GetCurrent().Name) -LogonType Interactive -RunLevel Limited -`$taskSettings = New-ScheduledTaskSettingsSet -MultipleInstances IgnoreNew -Register-ScheduledTask -TaskName "GameCult-Muninn" -Action `$taskAction -Trigger `$taskTrigger -Principal `$taskPrincipal -Settings `$taskSettings -Force | Out-Null + +function Write-HiddenCmdLauncher { + param( + [Parameter(Mandatory = `$true)] [string] `$CmdPath, + [Parameter(Mandatory = `$true)] [string] `$VbsPath + ) + + if (-not (Test-Path -LiteralPath `$CmdPath)) { + return + } + + `$launcherLines = @( + 'Set fso = CreateObject("Scripting.FileSystemObject")', + 'Set shell = CreateObject("WScript.Shell")', + "cmdPath = ""`$CmdPath""", + 'shell.CurrentDirectory = fso.GetParentFolderName(cmdPath)', + 'shell.Run """" & cmdPath & """", 0, False' + ) + Set-Content -LiteralPath `$VbsPath -Value `$launcherLines -Encoding ASCII +} + +function Register-HiddenVbsTask { + param( + [Parameter(Mandatory = `$true)] [string] `$TaskName, + [Parameter(Mandatory = `$true)] [string] `$VbsPath + ) + + if (-not (Test-Path -LiteralPath `$VbsPath)) { + return + } + + `$taskAction = New-ScheduledTaskAction -Execute "wscript.exe" -Argument "//B //Nologo ""`$VbsPath""" + `$taskTrigger = New-ScheduledTaskTrigger -Once -At ([DateTime]::Today.AddHours(23).AddMinutes(59)) + `$taskPrincipal = New-ScheduledTaskPrincipal -UserId ([System.Security.Principal.WindowsIdentity]::GetCurrent().Name) -LogonType Interactive -RunLevel Limited + `$taskSettings = New-ScheduledTaskSettingsSet -MultipleInstances IgnoreNew + Register-ScheduledTask -TaskName `$TaskName -Action `$taskAction -Trigger `$taskTrigger -Principal `$taskPrincipal -Settings `$taskSettings -Force | Out-Null +} + +function Assert-HiddenVbsTask { + param( + [Parameter(Mandatory = `$true)] [string] `$TaskName, + [Parameter(Mandatory = `$true)] [string] `$VbsPath + ) + + if (-not (Test-Path -LiteralPath `$VbsPath)) { + return + } + + `$task = Get-ScheduledTask -TaskName `$TaskName -ErrorAction Stop + `$action = @(`$task.Actions)[0] + if (`$action.Execute -notmatch '(^|\\)wscript\.exe$') { + throw "`$TaskName action executes `$(`$action.Execute), expected wscript.exe" + } + if (`$action.Arguments -notlike "*`$VbsPath*") { + throw "`$TaskName action arguments `$(`$action.Arguments) do not reference `$VbsPath" + } + if (`$action.Arguments -notlike "*//B*" -or `$action.Arguments -notlike "*//Nologo*") { + throw "`$TaskName action arguments `$(`$action.Arguments) do not force background WScript execution" + } +} + +Write-HiddenCmdLauncher -CmdPath `$activateCmd -VbsPath `$activateVbs +Write-HiddenCmdLauncher -CmdPath `$videoProofCmd -VbsPath `$videoProofVbs +Register-HiddenVbsTask -TaskName "GameCult-Muninn" -VbsPath `$vbsLauncher +Register-HiddenVbsTask -TaskName "GameCult-Muninn-Activate" -VbsPath `$activateVbs +Register-HiddenVbsTask -TaskName "GameCult-Muninn-VideoProof" -VbsPath `$videoProofVbs +Assert-HiddenVbsTask -TaskName "GameCult-Muninn" -VbsPath `$vbsLauncher +Assert-HiddenVbsTask -TaskName "GameCult-Muninn-Activate" -VbsPath `$activateVbs +Assert-HiddenVbsTask -TaskName "GameCult-Muninn-VideoProof" -VbsPath `$videoProofVbs Start-ScheduledTask -TaskName "GameCult-Muninn" "@