diff --git a/scripts/install-stack-startup-task.ps1 b/scripts/install-stack-startup-task.ps1 index 9718e03..f055a83 100644 --- a/scripts/install-stack-startup-task.ps1 +++ b/scripts/install-stack-startup-task.ps1 @@ -57,7 +57,9 @@ $taskNameValue = if (-not [string]::IsNullOrWhiteSpace($TaskName)) { } $action = New-ScheduledTaskAction -Execute "wscript.exe" -Argument "//B //nologo `"$hiddenLauncher`" -NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -File `"$startScript`"" +$action.WorkingDirectory = $repoRoot $trigger = New-ScheduledTaskTrigger -AtLogOn -User "$env:USERDOMAIN\$env:USERNAME" +$trigger.Delay = "PT2M" $settings = New-ScheduledTaskSettingsSet -StartWhenAvailable -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit (New-TimeSpan -Minutes 30) $principal = New-ScheduledTaskPrincipal -UserId "$env:USERDOMAIN\$env:USERNAME" -LogonType Interactive -RunLevel Limited $description = "Starts the VoidBot stack when this workstation user logs on so bot and worker do not stay dead after a reboot." diff --git a/scripts/start-voidbot-stack.ps1 b/scripts/start-voidbot-stack.ps1 index 84e0e3d..75eed17 100644 --- a/scripts/start-voidbot-stack.ps1 +++ b/scripts/start-voidbot-stack.ps1 @@ -3,9 +3,27 @@ $ErrorActionPreference = "Stop" $repoRoot = Split-Path -Parent $PSScriptRoot $envFile = Join-Path $repoRoot ".env" +$startupLogDir = Join-Path $repoRoot ".voidbot\logs" +$startupLogPath = Join-Path $startupLogDir "start-voidbot-stack.log" . (Join-Path $PSScriptRoot "voidbot-operations-dashboard-lib.ps1") Set-Location -LiteralPath $repoRoot +New-Item -ItemType Directory -Force -Path $startupLogDir | Out-Null + +try { + Start-Transcript -Path $startupLogPath -Append | Out-Null +} catch { +} + +trap { + try { + Stop-Transcript | Out-Null + } catch { + } + + throw +} + function Read-DotEnv { param( [Parameter(Mandatory = $true)] @@ -215,11 +233,10 @@ function Ensure-DockerOnPath { throw "Docker CLI is not available on PATH." } - & docker version *> $null - - if ($LASTEXITCODE -ne 0) { - throw "Docker is installed but the daemon is not ready." - } + Wait-Until -Condition { + & docker version *> $null + return ($LASTEXITCODE -eq 0) + } -FailureMessage "Docker is installed but the daemon is not ready." -Attempts 45 -SleepSeconds 2 } function Ensure-Qdrant { @@ -617,3 +634,8 @@ Write-Host "VoidBot stack is up." Write-Host "Status: $statusPath" Write-Host "Bot log: $botOut" Write-Host "Worker log: $workerOut" + +try { + Stop-Transcript | Out-Null +} catch { +} diff --git a/state/evidence.jsonl b/state/evidence.jsonl index b84e753..b1e521e 100644 --- a/state/evidence.jsonl +++ b/state/evidence.jsonl @@ -68,3 +68,4 @@ {"ts":"2026-05-09T18:08:46Z","type":"implementation","status":"ok","note":"Moderation rumination mojibake came from UTF-8 boundaries in the PowerShell runner, not corrupted canonical state. Explicitly decode redirected Codex stdout/stderr as UTF-8, read the saved final-message file as UTF-8, and write stdin through a UTF-8 StreamWriter for Windows PowerShell 5.1 compatibility."} {"ts":"2026-05-10T15:36:28Z","type":"implementation","status":"ok","note":"Heartbeat repo weather was re-injecting the same four-day commit window on every run because the repo-activity helper had no per-repo cursor. The helper now uses moderation state as an incremental cursor store, persists repo commit cutoffs through the canonical MessagePack-backed state seam, and suppresses already-injected commits by default so repeated sweeps return only genuinely new motion."} {"ts":"2026-05-11T01:27:37Z","type":"implementation","status":"ok","note":"Heartbeat Portuguese mojibake had two sources: the unattended send path was letting human text pass through Windows shell encoding, and PowerShell Get-Content stdout was still mangling UTF-8 moderation surfaces even when the underlying files were fine. Fixed by adding scripts/send-discord-message.ps1 plus BOM-aware content-file reads in scripts/send-discord-message.mjs, and steering the moderation loop through node scripts/export-moderation-context.mjs instead of raw Get-Content for doctrine/state bundles."} +{"ts":"2026-05-12T11:47:57Z","type":"implementation","status":"ok","note":"Logon startup failures were dying without a durable transcript and likely firing before Docker finished waking up after reboot. The stack startup script now appends .voidbot/logs/start-voidbot-stack.log, stops the transcript on failure, waits up to 90 seconds for docker version before giving up, and the logon task now runs with an explicit working directory plus a two-minute delay after logon."}