Delete deploy, restart, health and start/stop scripts for other services

Odin does not deploy, restart or health-probe anything: Idunn owns
deployment and daemon survival, and every service in this set is either
Idunn-deployed from its own repo recipe or archived. Removed from
scripts/: deploy-yggdrasil-{heimdall,repixelizer,source-app,streampixels}
(.ps1/.cmd, armed behind IDUNN_ACTUATOR=1) and the linux heimdall deploy;
restart-* (odin, stonks, vili, weksa, nightwing eve dashboard and browser
reference; several already exit 2 or throw as archived); health-* (odin,
voidbot, stonks, vili, weksa, mimir, nightwing, raven capture mux,
yggdrasil heimdall/repixelizer/streampixels/source-app; archived stubs and
orphans); start-odin.ps1 and stop-odin.ps1 (launched the deleted Node
coordinator).

Kept: write-gjallar-persona-cc.mjs (persona tooling, package.json
gjallar scripts) and the nightwing usb-move helpers, wasapi loopback,
firewall and wireguard scripts, none of which is a lifecycle actuator.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
soul-probe 2026-09-30 00:22:19 +02:00
commit 092ff997b4
39 changed files with 0 additions and 1898 deletions

View file

@ -1,10 +0,0 @@
@echo off
if not "%IDUNN_ACTUATOR%"=="1" (
echo This deployment wrapper is an Idunn actuator. Configure Idunn; do not deploy manually.
exit /b 1
)
if /I not "%IDUNN_COMMAND_AUTHORITY%"=="idunn-daemon" (
echo This deployment wrapper is an Idunn actuator. Configure Idunn; do not deploy manually.
exit /b 1
)
powershell.exe -NoProfile -ExecutionPolicy Bypass -File %~dp0deploy-yggdrasil-heimdall.ps1

View file

@ -1,156 +0,0 @@
param(
[string] $SshTarget = "yggdrasil",
[string] $RepoRoot = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "Heimdall"),
[string] $CultLibRoot = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "CultLib"),
[string] $AppUser = "heimdall",
[string] $RemoteAppHome = "/srv/heimdall",
[string] $RemoteTarballName = "heimdall-source.tar",
[string] $RemoteCultLibTarballName = "heimdall-cultlib.tar",
[string] $DeployScript = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "gamecult-ops\scripts\deploy-heimdall.sh"),
[string] $CheckScript = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "gamecult-ops\scripts\check-heimdall.sh"),
[string] $UpstreamRemote = "origin",
[string] $UpstreamBranch = "main",
[string] $CultLibUpstreamRemote = "origin",
[string] $CultLibUpstreamBranch = "main"
)
$ErrorActionPreference = "Stop"
if ($env:IDUNN_ACTUATOR -ne "1" -or $env:IDUNN_COMMAND_AUTHORITY -ne "idunn-daemon") {
throw "This deployment script is an Idunn actuator. Agents must configure Idunn release targets and let Idunn run deployment; do not invoke deploy scripts manually."
}
foreach ($path in @($RepoRoot, $CultLibRoot, $DeployScript, $CheckScript)) {
if (-not (Test-Path -LiteralPath $path)) {
throw "Required path not found: $path"
}
}
$sourceRef = "$UpstreamRemote/$UpstreamBranch"
$cultLibSourceRef = "$CultLibUpstreamRemote/$CultLibUpstreamBranch"
git -C $RepoRoot fetch --prune $UpstreamRemote $UpstreamBranch
if ($LASTEXITCODE -ne 0) { throw "git fetch failed for $RepoRoot $sourceRef" }
git -C $CultLibRoot fetch --prune $CultLibUpstreamRemote $CultLibUpstreamBranch
if ($LASTEXITCODE -ne 0) { throw "git fetch failed for $CultLibRoot $cultLibSourceRef" }
$heimdallCommit = (git -C $RepoRoot rev-parse $sourceRef).Trim()
if ([string]::IsNullOrWhiteSpace($heimdallCommit)) {
throw "Could not determine Heimdall git revision."
}
$cultLibCommit = (git -C $CultLibRoot rev-parse $cultLibSourceRef).Trim()
if ([string]::IsNullOrWhiteSpace($cultLibCommit)) {
throw "Could not determine CultLib git revision."
}
$scratch = Join-Path (Join-Path (Split-Path -Parent $PSScriptRoot) "scratch\idunn-deploy") "yggdrasil-heimdall"
$sourceTarPath = Join-Path $scratch $RemoteTarballName
$cultLibTarPath = Join-Path $scratch $RemoteCultLibTarballName
$manifestPath = Join-Path $scratch "deployment-manifest.txt"
New-Item -ItemType Directory -Force -Path $scratch | Out-Null
git -C $RepoRoot archive --format=tar --output=$sourceTarPath $sourceRef
if ($LASTEXITCODE -ne 0) {
throw "git archive failed for $RepoRoot $sourceRef"
}
if (Test-Path -LiteralPath $cultLibTarPath) {
Remove-Item -LiteralPath $cultLibTarPath -Force
}
git -C $CultLibRoot archive --format=tar --output=$cultLibTarPath $cultLibSourceRef packages/cultnet-ts packages/cultcache-ts
if ($LASTEXITCODE -ne 0) {
throw "CultLib tar build failed for $CultLibRoot $cultLibSourceRef"
}
$sourceHash = (Get-FileHash $sourceTarPath -Algorithm SHA256).Hash.ToLowerInvariant()
$cultLibHash = (Get-FileHash $cultLibTarPath -Algorithm SHA256).Hash.ToLowerInvariant()
$deployedAt = [DateTimeOffset]::UtcNow.ToString("O")
@(
"schema=gamecult.idunn.deployment_manifest.v1"
"appId=yggdrasil-heimdall"
"repoRoot=$RepoRoot"
"upstreamRemote=$UpstreamRemote"
"upstreamBranch=$UpstreamBranch"
"sourceRef=$sourceRef"
"gitCommit=$heimdallCommit"
"artifact=$RemoteTarballName"
"sha256=$sourceHash"
"cultLibRepoRoot=$CultLibRoot"
"cultLibUpstreamRemote=$CultLibUpstreamRemote"
"cultLibUpstreamBranch=$CultLibUpstreamBranch"
"cultLibSourceRef=$cultLibSourceRef"
"cultLibGitCommit=$cultLibCommit"
"cultLibArtifact=$RemoteCultLibTarballName"
"cultLibSha256=$cultLibHash"
"deployedAtUtc=$deployedAt"
) | Set-Content -Encoding ASCII -LiteralPath $manifestPath
$remoteDeploy = "/home/gamecultadmin/$([IO.Path]::GetFileName($DeployScript))"
$remoteCheck = "/home/gamecultadmin/$([IO.Path]::GetFileName($CheckScript))"
$remoteSourceTarball = "/home/gamecultadmin/$RemoteTarballName"
$remoteCultLibTarball = "/home/gamecultadmin/$RemoteCultLibTarballName"
$remoteManifest = "/home/gamecultadmin/yggdrasil-heimdall-deployment-manifest.txt"
$remoteRunner = "/home/gamecultadmin/run-yggdrasil-heimdall-deploy.sh"
$targetSourceTarball = "$RemoteAppHome/$RemoteTarballName"
$targetCultLibTarball = "$RemoteAppHome/$RemoteCultLibTarballName"
$targetManifest = "$RemoteAppHome/deployment-manifest.txt"
$sftpBatchPath = Join-Path $scratch "yggdrasil-heimdall-upload.sftp"
$runnerPath = Join-Path $scratch "run-yggdrasil-heimdall-deploy.sh"
$runnerScript = @"
#!/usr/bin/env bash
set -euo pipefail
sudo -n install -d -o '$AppUser' -g '$AppUser' '$RemoteAppHome'
sudo -n install -o '$AppUser' -g '$AppUser' -m 600 '$remoteSourceTarball' '$targetSourceTarball'
sudo -n install -o '$AppUser' -g '$AppUser' -m 600 '$remoteCultLibTarball' '$targetCultLibTarball'
sudo -n install -m 644 '$remoteManifest' '$targetManifest'
chmod +x '$remoteDeploy' '$remoteCheck'
sudo -n env GAMECULT_IDUNN_REMOTE_ACTUATOR=1 IDUNN_COMMAND_AUTHORITY=idunn-daemon bash '$remoteDeploy'
check_ok=0
for i in `$(seq 1 30); do
if sudo -n bash '$remoteCheck'; then
check_ok=1
break
fi
sleep 2
done
if [ "`$check_ok" -ne 1 ]; then
sudo -n bash '$remoteCheck'
exit 1
fi
"@.Replace("`r`n", "`n")
[System.IO.File]::WriteAllText($runnerPath, $runnerScript, [System.Text.Encoding]::ASCII)
@(
"put ""$sourceTarPath"" ""$remoteSourceTarball"""
"put ""$cultLibTarPath"" ""$remoteCultLibTarball"""
"put ""$DeployScript"" ""$remoteDeploy"""
"put ""$CheckScript"" ""$remoteCheck"""
"put ""$manifestPath"" ""$remoteManifest"""
"put ""$runnerPath"" ""$remoteRunner"""
) | Set-Content -Encoding ASCII -LiteralPath $sftpBatchPath
try {
& sftp.exe -b $sftpBatchPath $SshTarget
if ($LASTEXITCODE -ne 0) {
throw "sftp upload failed for yggdrasil-heimdall"
}
& ssh.exe -o BatchMode=yes -o ConnectTimeout=10 $SshTarget "chmod +x '$remoteRunner' && bash '$remoteRunner'"
$remoteExit = $LASTEXITCODE
& ssh.exe -o BatchMode=yes -o ConnectTimeout=10 $SshTarget "rm -f '$remoteRunner'"
if ($remoteExit -ne 0) {
throw "remote deploy/check failed for yggdrasil-heimdall"
}
}
finally {
Remove-Item -LiteralPath $runnerPath -Force -ErrorAction SilentlyContinue
Remove-Item -LiteralPath $sftpBatchPath -Force -ErrorAction SilentlyContinue
}
Write-Host "yggdrasil-heimdall deployed with CultLib snapshot."
Write-Host " heimdallCommit=$heimdallCommit"
Write-Host " cultLibCommit=$cultLibCommit"
Write-Host " artifactSha256=$sourceHash"
Write-Host " cultLibSha256=$cultLibHash"

View file

@ -1,10 +0,0 @@
@echo off
if not "%IDUNN_ACTUATOR%"=="1" (
echo This deployment wrapper is an Idunn actuator. Configure Idunn; do not deploy manually.
exit /b 1
)
if /I not "%IDUNN_COMMAND_AUTHORITY%"=="idunn-daemon" (
echo This deployment wrapper is an Idunn actuator. Configure Idunn; do not deploy manually.
exit /b 1
)
powershell.exe -NoProfile -ExecutionPolicy Bypass -File %~dp0deploy-yggdrasil-repixelizer.ps1

View file

@ -1,161 +0,0 @@
param(
[string] $SshTarget = "yggdrasil",
[string] $RepoRoot = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "repixelizer"),
[string] $CultLibRoot = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "CultLib"),
[string] $AppUser = "repixelizer",
[string] $RemoteAppHome = "/srv/repixelizer",
[string] $RemoteTarballName = "repixelizer-source.tar",
[string] $RemoteCultLibTarballName = "repixelizer-cultlib.tar",
[string] $DeployScript = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "gamecult-ops\scripts\deploy-repixelizer-gui.sh"),
[string] $CheckScript = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "gamecult-ops\scripts\check-repixelizer-gui.sh"),
[string] $UpstreamRemote = "origin",
[string] $UpstreamBranch = "main",
[string] $CultLibUpstreamRemote = "origin",
[string] $CultLibUpstreamBranch = "main"
)
$ErrorActionPreference = "Stop"
if ($env:IDUNN_ACTUATOR -ne "1" -or $env:IDUNN_COMMAND_AUTHORITY -ne "idunn-daemon") {
throw "This deployment script is an Idunn actuator. Agents must configure Idunn release targets and let Idunn run deployment; do not invoke deploy scripts manually."
}
foreach ($path in @($RepoRoot, $CultLibRoot, $DeployScript, $CheckScript)) {
if (-not (Test-Path -LiteralPath $path)) {
throw "Required path not found: $path"
}
}
$sourceRef = "$UpstreamRemote/$UpstreamBranch"
$cultLibSourceRef = "$CultLibUpstreamRemote/$CultLibUpstreamBranch"
git -C $RepoRoot fetch --prune $UpstreamRemote $UpstreamBranch
if ($LASTEXITCODE -ne 0) { throw "git fetch failed for $RepoRoot $sourceRef" }
git -C $CultLibRoot fetch --prune $CultLibUpstreamRemote $CultLibUpstreamBranch
if ($LASTEXITCODE -ne 0) { throw "git fetch failed for $CultLibRoot $cultLibSourceRef" }
$repixelizerCommit = (git -C $RepoRoot rev-parse $sourceRef).Trim()
if ([string]::IsNullOrWhiteSpace($repixelizerCommit)) {
throw "Could not determine Repixelizer git revision."
}
$cultLibCommit = (git -C $CultLibRoot rev-parse $cultLibSourceRef).Trim()
if ([string]::IsNullOrWhiteSpace($cultLibCommit)) {
throw "Could not determine CultLib git revision."
}
$scratch = Join-Path (Join-Path (Split-Path -Parent $PSScriptRoot) "scratch\idunn-deploy") "yggdrasil-repixelizer"
$sourceTarPath = Join-Path $scratch $RemoteTarballName
$cultLibTarPath = Join-Path $scratch $RemoteCultLibTarballName
$manifestPath = Join-Path $scratch "deployment-manifest.txt"
New-Item -ItemType Directory -Force -Path $scratch | Out-Null
git -C $RepoRoot archive --format=tar --output=$sourceTarPath $sourceRef
if ($LASTEXITCODE -ne 0) {
throw "git archive failed for $RepoRoot $sourceRef"
}
if (Test-Path -LiteralPath $cultLibTarPath) {
Remove-Item -LiteralPath $cultLibTarPath -Force
}
# All three Python packages. CultLib split packages/cultcache-py into
# cultcache-py / cultnet-py / cultmesh-py; module names did not change, so
# archiving only the first still succeeds and ships an incomplete library
# that fails later as an ImportError, far from this line.
git -C $CultLibRoot archive --format=tar --output=$cultLibTarPath $cultLibSourceRef packages/cultcache-py packages/cultnet-py packages/cultmesh-py
if ($LASTEXITCODE -ne 0) {
throw "CultLib tar build failed for $CultLibRoot $cultLibSourceRef"
}
$sourceHash = (Get-FileHash $sourceTarPath -Algorithm SHA256).Hash.ToLowerInvariant()
$cultLibHash = (Get-FileHash $cultLibTarPath -Algorithm SHA256).Hash.ToLowerInvariant()
$deployedAt = [DateTimeOffset]::UtcNow.ToString("O")
@(
"schema=gamecult.idunn.deployment_manifest.v1"
"appId=yggdrasil-repixelizer"
"repoRoot=$RepoRoot"
"upstreamRemote=$UpstreamRemote"
"upstreamBranch=$UpstreamBranch"
"sourceRef=$sourceRef"
"gitCommit=$repixelizerCommit"
"artifact=$RemoteTarballName"
"sha256=$sourceHash"
"cultLibRepoRoot=$CultLibRoot"
"cultLibUpstreamRemote=$CultLibUpstreamRemote"
"cultLibUpstreamBranch=$CultLibUpstreamBranch"
"cultLibSourceRef=$cultLibSourceRef"
"cultLibGitCommit=$cultLibCommit"
"cultLibArtifact=$RemoteCultLibTarballName"
"cultLibSha256=$cultLibHash"
"deployedAtUtc=$deployedAt"
) | Set-Content -Encoding ASCII -LiteralPath $manifestPath
$remoteDeploy = "/home/gamecultadmin/$([IO.Path]::GetFileName($DeployScript))"
$remoteCheck = "/home/gamecultadmin/$([IO.Path]::GetFileName($CheckScript))"
$remoteSourceTarball = "/home/gamecultadmin/$RemoteTarballName"
$remoteCultLibTarball = "/home/gamecultadmin/$RemoteCultLibTarballName"
$remoteManifest = "/home/gamecultadmin/yggdrasil-repixelizer-deployment-manifest.txt"
$remoteRunner = "/home/gamecultadmin/run-yggdrasil-repixelizer-deploy.sh"
$targetSourceTarball = "$RemoteAppHome/$RemoteTarballName"
$targetCultLibTarball = "$RemoteAppHome/$RemoteCultLibTarballName"
$targetManifest = "$RemoteAppHome/deployment-manifest.txt"
$sftpBatchPath = Join-Path $scratch "yggdrasil-repixelizer-upload.sftp"
$runnerPath = Join-Path $scratch "run-yggdrasil-repixelizer-deploy.sh"
$runnerScript = @"
#!/usr/bin/env bash
set -euo pipefail
sudo -n install -d -o '$AppUser' -g '$AppUser' '$RemoteAppHome'
sudo -n install -o '$AppUser' -g '$AppUser' -m 600 '$remoteSourceTarball' '$targetSourceTarball'
sudo -n install -o '$AppUser' -g '$AppUser' -m 600 '$remoteCultLibTarball' '$targetCultLibTarball'
sudo -n install -m 644 '$remoteManifest' '$targetManifest'
chmod +x '$remoteDeploy' '$remoteCheck'
sudo -n env GAMECULT_IDUNN_REMOTE_ACTUATOR=1 IDUNN_COMMAND_AUTHORITY=idunn-daemon bash '$remoteDeploy'
check_ok=0
for i in `$(seq 1 30); do
if sudo -n bash '$remoteCheck'; then
check_ok=1
break
fi
sleep 2
done
if [ "`$check_ok" -ne 1 ]; then
sudo -n bash '$remoteCheck'
exit 1
fi
"@.Replace("`r`n", "`n")
[System.IO.File]::WriteAllText($runnerPath, $runnerScript, [System.Text.Encoding]::ASCII)
@(
"put ""$sourceTarPath"" ""$remoteSourceTarball"""
"put ""$cultLibTarPath"" ""$remoteCultLibTarball"""
"put ""$DeployScript"" ""$remoteDeploy"""
"put ""$CheckScript"" ""$remoteCheck"""
"put ""$manifestPath"" ""$remoteManifest"""
"put ""$runnerPath"" ""$remoteRunner"""
) | Set-Content -Encoding ASCII -LiteralPath $sftpBatchPath
try {
& sftp.exe -b $sftpBatchPath $SshTarget
if ($LASTEXITCODE -ne 0) {
throw "sftp upload failed for yggdrasil-repixelizer"
}
& ssh.exe -o BatchMode=yes -o ConnectTimeout=10 $SshTarget "chmod +x '$remoteRunner' && bash '$remoteRunner'"
$remoteExit = $LASTEXITCODE
& ssh.exe -o BatchMode=yes -o ConnectTimeout=10 $SshTarget "rm -f '$remoteRunner'"
if ($remoteExit -ne 0) {
throw "remote deploy/check failed for yggdrasil-repixelizer"
}
}
finally {
Remove-Item -LiteralPath $runnerPath -Force -ErrorAction SilentlyContinue
Remove-Item -LiteralPath $sftpBatchPath -Force -ErrorAction SilentlyContinue
}
Write-Host "yggdrasil-repixelizer deployed with CultLib snapshot."
Write-Host " repixelizerCommit=$repixelizerCommit"
Write-Host " cultLibCommit=$cultLibCommit"
Write-Host " artifactSha256=$sourceHash"
Write-Host " cultLibSha256=$cultLibHash"

View file

@ -1,137 +0,0 @@
param(
[Parameter(Mandatory = $true)] [string] $AppId,
[Parameter(Mandatory = $true)] [string] $RepoRoot,
[Parameter(Mandatory = $true)] [string] $AppUser,
[Parameter(Mandatory = $true)] [string] $RemoteAppHome,
[Parameter(Mandatory = $true)] [string] $RemoteTarballName,
[Parameter(Mandatory = $true)] [string] $DeployScript,
[Parameter(Mandatory = $true)] [string] $CheckScript,
[string] $SshTarget = "yggdrasil",
[string] $UpstreamRemote = "origin",
[string] $UpstreamBranch = "main",
[string] $StateMigrationScript = ""
)
$ErrorActionPreference = "Stop"
if ($env:IDUNN_ACTUATOR -ne "1") {
throw "This deployment script is an Idunn actuator. Agents must configure Idunn release targets and let Idunn run deployment; do not invoke deploy scripts manually."
}
if (-not (Test-Path -LiteralPath $RepoRoot)) {
throw "Repo root not found: $RepoRoot"
}
if (-not (Test-Path -LiteralPath $DeployScript)) {
throw "Deploy script not found: $DeployScript"
}
if (-not (Test-Path -LiteralPath $CheckScript)) {
throw "Check script not found: $CheckScript"
}
if (-not [string]::IsNullOrWhiteSpace($StateMigrationScript) -and -not (Test-Path -LiteralPath $StateMigrationScript)) {
throw "State migration script not found: $StateMigrationScript"
}
git -C $RepoRoot fetch --prune $UpstreamRemote $UpstreamBranch
if ($LASTEXITCODE -ne 0) {
throw "git fetch failed for $RepoRoot $UpstreamRemote/$UpstreamBranch"
}
$sourceRef = "$UpstreamRemote/$UpstreamBranch"
$commit = (git -C $RepoRoot rev-parse $sourceRef).Trim()
if ([string]::IsNullOrWhiteSpace($commit)) {
throw "Could not determine git revision for $RepoRoot $sourceRef"
}
$scratch = Join-Path (Join-Path (Split-Path -Parent $PSScriptRoot) "scratch\idunn-deploy") $AppId
$tarPath = Join-Path $scratch $RemoteTarballName
$manifestPath = Join-Path $scratch "deployment-manifest.txt"
New-Item -ItemType Directory -Force -Path $scratch | Out-Null
git -C $RepoRoot archive --format=tar --output=$tarPath $sourceRef
if ($LASTEXITCODE -ne 0) {
throw "git archive failed for $RepoRoot $sourceRef"
}
$hash = (Get-FileHash $tarPath -Algorithm SHA256).Hash.ToLowerInvariant()
$deployedAt = [DateTimeOffset]::UtcNow.ToString("O")
@(
"schema=gamecult.idunn.deployment_manifest.v1"
"appId=$AppId"
"repoRoot=$RepoRoot"
"upstreamRemote=$UpstreamRemote"
"upstreamBranch=$UpstreamBranch"
"sourceRef=$sourceRef"
"gitCommit=$commit"
"artifact=$RemoteTarballName"
"sha256=$hash"
"deployedAtUtc=$deployedAt"
) | Set-Content -Encoding ASCII -LiteralPath $manifestPath
$remoteDeploy = "/home/gamecultadmin/$([IO.Path]::GetFileName($DeployScript))"
$remoteCheck = "/home/gamecultadmin/$([IO.Path]::GetFileName($CheckScript))"
$remoteMigration = if ([string]::IsNullOrWhiteSpace($StateMigrationScript)) { "" } else { "/home/gamecultadmin/$([IO.Path]::GetFileName($StateMigrationScript))" }
$remoteTarball = "/home/gamecultadmin/$RemoteTarballName"
$remoteManifest = "/home/gamecultadmin/$AppId-deployment-manifest.txt"
$remoteRunner = "/home/gamecultadmin/run-$AppId-deploy.sh"
$targetTarball = "$RemoteAppHome/$RemoteTarballName"
$targetManifest = "$RemoteAppHome/deployment-manifest.txt"
$sshArgs = @("-o", "BatchMode=yes", "-o", "ConnectTimeout=10", $SshTarget)
$scpArgs = @("-o", "BatchMode=yes", "-o", "ConnectTimeout=10")
$runnerPath = Join-Path $scratch "run-$AppId-deploy.sh"
$runnerScript = @"
#!/usr/bin/env bash
set -euo pipefail
sudo -n install -d -o '$AppUser' -g '$AppUser' '$RemoteAppHome'
sudo -n install -o '$AppUser' -g '$AppUser' -m 600 '$remoteTarball' '$targetTarball'
sudo -n install -m 644 '$remoteManifest' '$targetManifest'
chmod +x '$remoteDeploy' '$remoteCheck'
if [ -n '$remoteMigration' ]; then
chmod +x '$remoteMigration'
sudo -n bash '$remoteMigration'
fi
sudo -n bash '$remoteDeploy'
check_ok=0
for i in `$(seq 1 30); do
if sudo -n bash '$remoteCheck'; then
check_ok=1
break
fi
sleep 2
done
if [ "`$check_ok" -ne 1 ]; then
sudo -n bash '$remoteCheck'
exit 1
fi
"@.Replace("`r`n", "`n")
[System.IO.File]::WriteAllText($runnerPath, $runnerScript, [System.Text.Encoding]::ASCII)
scp.exe @scpArgs $tarPath "${SshTarget}:$remoteTarball"
if ($LASTEXITCODE -ne 0) { throw "scp source tarball failed for $AppId" }
scp.exe @scpArgs $DeployScript "${SshTarget}:$remoteDeploy"
if ($LASTEXITCODE -ne 0) { throw "scp deploy script failed for $AppId" }
scp.exe @scpArgs $CheckScript "${SshTarget}:$remoteCheck"
if ($LASTEXITCODE -ne 0) { throw "scp check script failed for $AppId" }
if (-not [string]::IsNullOrWhiteSpace($StateMigrationScript)) {
scp.exe @scpArgs $StateMigrationScript "${SshTarget}:$remoteMigration"
if ($LASTEXITCODE -ne 0) { throw "scp state migration script failed for $AppId" }
}
scp.exe @scpArgs $manifestPath "${SshTarget}:$remoteManifest"
if ($LASTEXITCODE -ne 0) { throw "scp manifest failed for $AppId" }
scp.exe @scpArgs $runnerPath "${SshTarget}:$remoteRunner"
if ($LASTEXITCODE -ne 0) { throw "scp runner script failed for $AppId" }
ssh.exe @sshArgs "chmod +x '$remoteRunner' && bash '$remoteRunner'"
$remoteExit = $LASTEXITCODE
ssh.exe @sshArgs "rm -f '$remoteRunner'"
if ($remoteExit -ne 0) {
throw "remote deploy/check failed for $AppId"
}
Remove-Item -LiteralPath $runnerPath -Force -ErrorAction SilentlyContinue
Write-Host "$AppId deployed to Yggdrasil from $sourceRef at $commit."
Write-Host " artifactSha256=$hash"

View file

@ -1,10 +0,0 @@
@echo off
if not "%IDUNN_ACTUATOR%"=="1" (
echo This deployment wrapper is an Idunn actuator. Configure Idunn; do not deploy manually.
exit /b 1
)
if /I not "%IDUNN_COMMAND_AUTHORITY%"=="idunn-daemon" (
echo This deployment wrapper is an Idunn actuator. Configure Idunn; do not deploy manually.
exit /b 1
)
powershell.exe -NoProfile -ExecutionPolicy Bypass -File %~dp0deploy-yggdrasil-streampixels.ps1

View file

@ -1,156 +0,0 @@
param(
[string] $SshTarget = "yggdrasil",
[string] $RepoRoot = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "StreamPixels"),
[string] $CultLibRoot = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "CultLib"),
[string] $AppUser = "streampixels",
[string] $RemoteAppHome = "/srv/streampixels",
[string] $RemoteTarballName = "streampixels-source.tar",
[string] $RemoteCultLibTarballName = "streampixels-cultlib.tar",
[string] $DeployScript = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "gamecult-ops\scripts\deploy-streampixels-preview.sh"),
[string] $CheckScript = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "gamecult-ops\scripts\check-streampixels-preview.sh"),
[string] $UpstreamRemote = "origin",
[string] $UpstreamBranch = "main",
[string] $CultLibUpstreamRemote = "origin",
[string] $CultLibUpstreamBranch = "main"
)
$ErrorActionPreference = "Stop"
if ($env:IDUNN_ACTUATOR -ne "1" -or $env:IDUNN_COMMAND_AUTHORITY -ne "idunn-daemon") {
throw "This deployment script is an Idunn actuator. Agents must configure Idunn release targets and let Idunn run deployment; do not invoke deploy scripts manually."
}
foreach ($path in @($RepoRoot, $CultLibRoot, $DeployScript, $CheckScript)) {
if (-not (Test-Path -LiteralPath $path)) {
throw "Required path not found: $path"
}
}
$sourceRef = "$UpstreamRemote/$UpstreamBranch"
$cultLibSourceRef = "$CultLibUpstreamRemote/$CultLibUpstreamBranch"
git -C $RepoRoot fetch --prune $UpstreamRemote $UpstreamBranch
if ($LASTEXITCODE -ne 0) { throw "git fetch failed for $RepoRoot $sourceRef" }
git -C $CultLibRoot fetch --prune $CultLibUpstreamRemote $CultLibUpstreamBranch
if ($LASTEXITCODE -ne 0) { throw "git fetch failed for $CultLibRoot $cultLibSourceRef" }
$streamPixelsCommit = (git -C $RepoRoot rev-parse $sourceRef).Trim()
if ([string]::IsNullOrWhiteSpace($streamPixelsCommit)) {
throw "Could not determine StreamPixels git revision."
}
$cultLibCommit = (git -C $CultLibRoot rev-parse $cultLibSourceRef).Trim()
if ([string]::IsNullOrWhiteSpace($cultLibCommit)) {
throw "Could not determine CultLib git revision."
}
$scratch = Join-Path (Join-Path (Split-Path -Parent $PSScriptRoot) "scratch\idunn-deploy") "yggdrasil-streampixels"
$sourceTarPath = Join-Path $scratch $RemoteTarballName
$cultLibTarPath = Join-Path $scratch $RemoteCultLibTarballName
$manifestPath = Join-Path $scratch "deployment-manifest.txt"
New-Item -ItemType Directory -Force -Path $scratch | Out-Null
git -C $RepoRoot archive --format=tar --output=$sourceTarPath $sourceRef
if ($LASTEXITCODE -ne 0) {
throw "git archive failed for $RepoRoot $sourceRef"
}
if (Test-Path -LiteralPath $cultLibTarPath) {
Remove-Item -LiteralPath $cultLibTarPath -Force
}
git -C $CultLibRoot archive --format=tar --output=$cultLibTarPath $cultLibSourceRef package.json package-lock.json scripts/run-typescript-workspaces.mjs contracts/cultnet packages/cultcache-ts packages/cultnet-ts packages/cultmesh-ts packages/cultmesh-browser
if ($LASTEXITCODE -ne 0) {
throw "CultLib tar build failed for $CultLibRoot $cultLibSourceRef"
}
$sourceHash = (Get-FileHash $sourceTarPath -Algorithm SHA256).Hash.ToLowerInvariant()
$cultLibHash = (Get-FileHash $cultLibTarPath -Algorithm SHA256).Hash.ToLowerInvariant()
$deployedAt = [DateTimeOffset]::UtcNow.ToString("O")
@(
"schema=gamecult.idunn.deployment_manifest.v1"
"appId=yggdrasil-streampixels"
"repoRoot=$RepoRoot"
"upstreamRemote=$UpstreamRemote"
"upstreamBranch=$UpstreamBranch"
"sourceRef=$sourceRef"
"gitCommit=$streamPixelsCommit"
"artifact=$RemoteTarballName"
"sha256=$sourceHash"
"cultLibRepoRoot=$CultLibRoot"
"cultLibUpstreamRemote=$CultLibUpstreamRemote"
"cultLibUpstreamBranch=$CultLibUpstreamBranch"
"cultLibSourceRef=$cultLibSourceRef"
"cultLibGitCommit=$cultLibCommit"
"cultLibArtifact=$RemoteCultLibTarballName"
"cultLibSha256=$cultLibHash"
"deployedAtUtc=$deployedAt"
) | Set-Content -Encoding ASCII -LiteralPath $manifestPath
$remoteDeploy = "/home/gamecultadmin/$([IO.Path]::GetFileName($DeployScript))"
$remoteCheck = "/home/gamecultadmin/$([IO.Path]::GetFileName($CheckScript))"
$remoteSourceTarball = "/home/gamecultadmin/$RemoteTarballName"
$remoteCultLibTarball = "/home/gamecultadmin/$RemoteCultLibTarballName"
$remoteManifest = "/home/gamecultadmin/yggdrasil-streampixels-deployment-manifest.txt"
$remoteRunner = "/home/gamecultadmin/run-yggdrasil-streampixels-deploy.sh"
$targetSourceTarball = "$RemoteAppHome/$RemoteTarballName"
$targetCultLibTarball = "$RemoteAppHome/$RemoteCultLibTarballName"
$targetManifest = "$RemoteAppHome/deployment-manifest.txt"
$sftpBatchPath = Join-Path $scratch "yggdrasil-streampixels-upload.sftp"
$runnerPath = Join-Path $scratch "run-yggdrasil-streampixels-deploy.sh"
$runnerScript = @"
#!/usr/bin/env bash
set -euo pipefail
sudo -n install -d -o '$AppUser' -g '$AppUser' '$RemoteAppHome'
sudo -n install -o '$AppUser' -g '$AppUser' -m 600 '$remoteSourceTarball' '$targetSourceTarball'
sudo -n install -o '$AppUser' -g '$AppUser' -m 600 '$remoteCultLibTarball' '$targetCultLibTarball'
sudo -n install -m 644 '$remoteManifest' '$targetManifest'
chmod +x '$remoteDeploy' '$remoteCheck'
sudo -n env GAMECULT_IDUNN_REMOTE_ACTUATOR=1 IDUNN_COMMAND_AUTHORITY=idunn-daemon bash '$remoteDeploy'
check_ok=0
for i in `$(seq 1 30); do
if sudo -n bash '$remoteCheck'; then
check_ok=1
break
fi
sleep 2
done
if [ "`$check_ok" -ne 1 ]; then
sudo -n bash '$remoteCheck'
exit 1
fi
"@.Replace("`r`n", "`n")
[System.IO.File]::WriteAllText($runnerPath, $runnerScript, [System.Text.Encoding]::ASCII)
@(
"put ""$sourceTarPath"" ""$remoteSourceTarball"""
"put ""$cultLibTarPath"" ""$remoteCultLibTarball"""
"put ""$DeployScript"" ""$remoteDeploy"""
"put ""$CheckScript"" ""$remoteCheck"""
"put ""$manifestPath"" ""$remoteManifest"""
"put ""$runnerPath"" ""$remoteRunner"""
) | Set-Content -Encoding ASCII -LiteralPath $sftpBatchPath
try {
& sftp.exe -b $sftpBatchPath $SshTarget
if ($LASTEXITCODE -ne 0) {
throw "sftp upload failed for yggdrasil-streampixels"
}
& ssh.exe -o BatchMode=yes -o ConnectTimeout=10 $SshTarget "chmod +x '$remoteRunner' && bash '$remoteRunner'"
$remoteExit = $LASTEXITCODE
& ssh.exe -o BatchMode=yes -o ConnectTimeout=10 $SshTarget "rm -f '$remoteRunner'"
if ($remoteExit -ne 0) {
throw "remote deploy/check failed for yggdrasil-streampixels"
}
}
finally {
Remove-Item -LiteralPath $runnerPath -Force -ErrorAction SilentlyContinue
Remove-Item -LiteralPath $sftpBatchPath -Force -ErrorAction SilentlyContinue
}
Write-Host "yggdrasil-streampixels deployed with CultLib snapshot."
Write-Host " streamPixelsCommit=$streamPixelsCommit"
Write-Host " cultLibCommit=$cultLibCommit"
Write-Host " artifactSha256=$sourceHash"
Write-Host " cultLibSha256=$cultLibHash"

View file

@ -1,3 +0,0 @@
@echo off
echo health-mimir-eve-dashboard.cmd archived: Mimir Eve dashboard health is daemon-published over CultNet/RUDP as mimir.cultnet-rudp-provider-health. Do not probe localhost HTTP for daemon health. 1>&2
exit /b 2

View file

@ -1,3 +0,0 @@
@echo off
echo health-nightwing-eve-browser-reference.cmd archived: Nightwing Eve browser reference health is daemon-published over CultNet/RUDP as nightwing.cultnet-rudp-browser-reference-health. Use health-nightwing-eve-browser-reference.ps1 only as an explicit witness inspection, not Idunn health truth.
exit /b 2

View file

@ -1,335 +0,0 @@
param(
[string] $SshTarget = "nightwing",
[string] $ExpectedDocumentRoot = "/opt/gamecult/eve-browser-reference",
[string] $RemoteCultCacheWitness = "/var/lib/gamecult/eve-browser-reference/cultcache/eve-browser-reference.service.cc",
[int] $MaxWitnessAgeSeconds = 120
)
$ErrorActionPreference = "Stop"
function Fail-IdunnHealth {
param(
[string] $State,
[string] $Message
)
Write-Output "idunn.health.state=$State"
throw $Message
}
function Invoke-SshText {
param(
[string] $Command,
[string] $FailureMessage,
[string] $FailureState = "failed"
)
$output = ssh.exe -o BatchMode=yes -o ConnectTimeout=5 $SshTarget $Command
if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($output)) {
Fail-IdunnHealth -State $FailureState -Message $FailureMessage
}
return $output
}
function Get-CultCacheInspection {
param(
[string] $WitnessCopyPath,
[string] $InspectorPackageJson
)
$nodeScript = @'
const fs = require("fs");
const { createRequire } = require("module");
const witnessCopyPath = process.argv[2];
const inspectorPackageJson = process.argv[3];
const requireCultCacheInspection = createRequire(inspectorPackageJson);
const { inspectCultCacheBytes } = requireCultCacheInspection("cultcache-ts");
const inspection = inspectCultCacheBytes(witnessCopyPath, fs.readFileSync(witnessCopyPath));
function firstRecord(schemaName) {
return inspection.records.find((record) => record.schemaName === schemaName) ?? null;
}
function previewArray(record) {
return Array.isArray(record?.payloadPreview) ? record.payloadPreview : [];
}
function normalizeRecord(schemaName) {
const record = firstRecord(schemaName);
if (!record) {
return null;
}
const preview = previewArray(record);
switch (schemaName) {
case "mimir.eve_browser_reference_manifest":
return {
schemaName: record.schemaName,
storedAt: record.storedAt,
daemonId: preview[0] ?? "",
siteTitle: preview[1] ?? "",
documentRoot: preview[2] ?? "",
entryPoint: preview[3] ?? "",
port: preview[4] ?? 0,
assetCount: Array.isArray(preview[5]) ? preview[5].length : 0,
surfaceTransport: preview[6] ?? "",
};
case "mimir.eve_browser_reference_static_surface":
return {
schemaName: record.schemaName,
storedAt: record.storedAt,
daemonId: preview[0] ?? "",
updatedAtUtc: preview[1] ?? "",
documentRoot: preview[2] ?? "",
entryPoint: preview[3] ?? "",
assetCount: Array.isArray(preview[4]) ? preview[4].length : 0,
fixtureCount: Array.isArray(preview[5]) ? preview[5].length : 0,
currentCutLine: preview[6] ?? "",
};
case "mimir.eve_browser_reference_command_boundary":
return {
schemaName: record.schemaName,
storedAt: record.storedAt,
daemonId: preview[0] ?? "",
updatedAtUtc: preview[1] ?? "",
mode: preview[2] ?? "",
writesAccepted: preview[3] === true,
operatorInputAuthority: preview[4] ?? "",
lifecycleAuthority: preview[5] ?? "",
acceptedCommands: Array.isArray(preview[6]) ? preview[6] : [],
rejectedCommands: Array.isArray(preview[7]) ? preview[7] : [],
};
case "mimir.eve_browser_reference_transport_profile":
return {
schemaName: record.schemaName,
storedAt: record.storedAt,
daemonId: preview[0] ?? "",
updatedAtUtc: preview[1] ?? "",
currentState: preview[2] ?? "",
inputTransport: preview[3] ?? "",
outputTransport: preview[4] ?? "",
healthContract: preview[5] ?? "",
idunnRudpHealth: preview[6] ?? "",
witnessPath: preview[7] ?? "",
currentCutLine: preview[8] ?? "",
};
case "idunn.daemon_health":
return {
schemaName: record.schemaName,
storedAt: record.storedAt,
daemonId: preview[0] ?? "",
state: preview[1] ?? "",
detail: preview[2] ?? "",
observedAt: preview[3] ?? "",
healthContract: preview[4] ?? "",
publicationSource: preview[5] ?? "",
transport: preview[6] ?? "",
};
default:
return {
schemaName: record.schemaName,
storedAt: record.storedAt,
};
}
}
console.log(JSON.stringify({
format: inspection.format,
catalogSchemaVersions: inspection.catalog.map((entry) => entry.schemaVersion),
manifest: normalizeRecord("mimir.eve_browser_reference_manifest"),
staticSurface: normalizeRecord("mimir.eve_browser_reference_static_surface"),
commandBoundary: normalizeRecord("mimir.eve_browser_reference_command_boundary"),
transportProfile: normalizeRecord("mimir.eve_browser_reference_transport_profile"),
daemonHealth: normalizeRecord("idunn.daemon_health"),
}));
'@
$inspectionJson = $nodeScript | node - $WitnessCopyPath $InspectorPackageJson
if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($inspectionJson)) {
Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference CultCache witness inspection failed."
}
try {
return $inspectionJson | ConvertFrom-Json
} catch {
Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference CultCache inspection returned malformed JSON."
}
}
ssh.exe -o BatchMode=yes -o ConnectTimeout=5 $SshTarget "systemctl is-active --quiet nightwing-eve-browser-reference.service"
if ($LASTEXITCODE -ne 0) {
Fail-IdunnHealth -State "failed" -Message "nightwing-eve-browser-reference.service is not active on Nightwing."
}
$cultCacheStat = Invoke-SshText `
-Command "stat -c '%s %Y %U %G' '$RemoteCultCacheWitness' 2>/dev/null" `
-FailureMessage "Nightwing Eve browser reference CultCache witness is missing at $RemoteCultCacheWitness."
$cultCacheParts = $cultCacheStat.Trim() -split '\s+'
if ($cultCacheParts.Length -lt 4) {
Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference CultCache witness stat output was malformed: $cultCacheStat"
}
$cultCacheSize = [int64]$cultCacheParts[0]
$cultCacheModifiedUtc = [DateTimeOffset]::FromUnixTimeSeconds([int64]$cultCacheParts[1])
$cultCacheOwner = $cultCacheParts[2]
$cultCacheGroup = $cultCacheParts[3]
$cultCacheAgeSeconds = ([DateTimeOffset]::UtcNow - $cultCacheModifiedUtc).TotalSeconds
if ($cultCacheSize -le 0) {
Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference CultCache witness at $RemoteCultCacheWitness is empty."
}
if ($cultCacheAgeSeconds -gt $MaxWitnessAgeSeconds) {
Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference CultCache witness is stale ($([math]::Round($cultCacheAgeSeconds))s old)."
}
if ($cultCacheOwner -ne "metacrat" -or $cultCacheGroup -ne "metacrat") {
Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference CultCache witness owner is ${cultCacheOwner}:$cultCacheGroup, expected metacrat:metacrat."
}
try {
$cultCacheInspectorPackageJson = (Resolve-Path (Join-Path $PSScriptRoot "..\..\CultLib\packages\cultcache-ts\package.json")).Path
} catch {
Fail-IdunnHealth -State "failed" -Message "CultCache inspector package is missing from the local Odin body."
}
$cultCacheWitnessCopy = Join-Path ([System.IO.Path]::GetTempPath()) ("nightwing-eve-browser-reference-" + [Guid]::NewGuid().ToString("N") + ".cc")
try {
$remoteCultCacheBase64 = Invoke-SshText `
-Command "base64 -w0 '$RemoteCultCacheWitness' 2>/dev/null" `
-FailureMessage "Nightwing Eve browser reference CultCache witness could not be copied from Nightwing."
[System.IO.File]::WriteAllBytes($cultCacheWitnessCopy, [Convert]::FromBase64String($remoteCultCacheBase64.Trim()))
$inspection = Get-CultCacheInspection -WitnessCopyPath $cultCacheWitnessCopy -InspectorPackageJson $cultCacheInspectorPackageJson
} catch [FormatException] {
Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference CultCache witness copy was not valid base64."
} finally {
if (Test-Path $cultCacheWitnessCopy) {
Remove-Item $cultCacheWitnessCopy -Force -ErrorAction SilentlyContinue
}
}
if ($inspection.format -ne "cultcache.store.v1") {
Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference CultCache witness has unexpected format '$($inspection.format)'."
}
$requiredCultCacheSchemas = @(
"mimir.eve_browser_reference_manifest.v1",
"mimir.eve_browser_reference_static_surface.v1",
"mimir.eve_browser_reference_command_boundary.v1",
"mimir.eve_browser_reference_transport_profile.v1",
"idunn.daemon_health.v1"
)
$publishedCultCacheSchemas = @($inspection.catalogSchemaVersions)
foreach ($schema in $requiredCultCacheSchemas) {
if ($publishedCultCacheSchemas -notcontains $schema) {
Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference CultCache witness is missing schema '$schema'."
}
}
if ($null -eq $inspection.manifest) {
Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference CultCache witness is missing its manifest record."
}
if ($inspection.manifest.documentRoot -ne $ExpectedDocumentRoot) {
Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference manifest document root is '$($inspection.manifest.documentRoot)', expected '$ExpectedDocumentRoot'."
}
if ($inspection.manifest.entryPoint -ne "index.html") {
Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference manifest entry point is '$($inspection.manifest.entryPoint)', expected 'index.html'."
}
if ($inspection.manifest.surfaceTransport -ne "static-http-lowering") {
Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference manifest transport is '$($inspection.manifest.surfaceTransport)', expected 'static-http-lowering'."
}
if ($null -eq $inspection.staticSurface) {
Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference CultCache witness is missing its static-surface record."
}
if ($inspection.staticSurface.documentRoot -ne $ExpectedDocumentRoot) {
Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference static-surface document root is '$($inspection.staticSurface.documentRoot)', expected '$ExpectedDocumentRoot'."
}
if ($null -eq $inspection.commandBoundary) {
Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference CultCache witness is missing its command boundary record."
}
if ($inspection.commandBoundary.mode -ne "static-read-only-lowering") {
Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference command boundary mode is '$($inspection.commandBoundary.mode)', expected 'static-read-only-lowering'."
}
if ($inspection.commandBoundary.writesAccepted) {
Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference command boundary unexpectedly accepts writes."
}
if ($inspection.commandBoundary.lifecycleAuthority -ne "idunn-supervisor-command.restart") {
Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference lifecycle authority is '$($inspection.commandBoundary.lifecycleAuthority)', expected 'idunn-supervisor-command.restart'."
}
if ($null -eq $inspection.transportProfile) {
Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference CultCache witness is missing its transport profile record."
}
if ($inspection.transportProfile.currentState -ne "partial-rudp-health-and-provider-store-live") {
Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference transport profile state is '$($inspection.transportProfile.currentState)', expected 'partial-rudp-health-and-provider-store-live'."
}
if ($inspection.transportProfile.inputTransport -ne "http-static-lowering") {
Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference input transport is '$($inspection.transportProfile.inputTransport)', expected 'http-static-lowering'."
}
if ($inspection.transportProfile.outputTransport -ne "daemon-owned-cultcache-boundary-store + daemon-published-rudp-health") {
Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference output transport is '$($inspection.transportProfile.outputTransport)', expected 'daemon-owned-cultcache-boundary-store + daemon-published-rudp-health'."
}
if ($inspection.transportProfile.healthContract -ne "nightwing.cultnet-rudp-browser-reference-health") {
Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference health contract is '$($inspection.transportProfile.healthContract)', expected 'nightwing.cultnet-rudp-browser-reference-health'."
}
if ($inspection.transportProfile.idunnRudpHealth -ne "idunn.health-published-separately") {
Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference transport profile Idunn health publication is '$($inspection.transportProfile.idunnRudpHealth)', expected 'idunn.health-published-separately'."
}
if ($inspection.transportProfile.witnessPath -ne $RemoteCultCacheWitness) {
Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference transport profile witness path is '$($inspection.transportProfile.witnessPath)', expected '$RemoteCultCacheWitness'."
}
if ($null -eq $inspection.daemonHealth) {
Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference CultCache witness is missing its daemon-health record."
}
if ($inspection.daemonHealth.daemonId -ne "nightwing-eve-browser-reference") {
Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference daemon-health record advertises daemon '$($inspection.daemonHealth.daemonId)', expected 'nightwing-eve-browser-reference'."
}
if ($inspection.daemonHealth.state -ne "healthy") {
Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference daemon-health state is '$($inspection.daemonHealth.state)', expected 'healthy'."
}
if ($inspection.daemonHealth.healthContract -ne "nightwing.cultnet-rudp-browser-reference-health") {
Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference daemon-health contract is '$($inspection.daemonHealth.healthContract)', expected 'nightwing.cultnet-rudp-browser-reference-health'."
}
if ($inspection.daemonHealth.publicationSource -ne "daemon-published") {
Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference daemon-health publication source is '$($inspection.daemonHealth.publicationSource)', expected 'daemon-published'."
}
if ($inspection.daemonHealth.transport -ne "cultnet.transport.rudp.v0") {
Fail-IdunnHealth -State "degraded" -Message "Nightwing Eve browser reference daemon-health transport is '$($inspection.daemonHealth.transport)', expected 'cultnet.transport.rudp.v0'."
}
try {
$daemonHealthObservedAtUtc = [DateTimeOffset]::Parse($inspection.daemonHealth.observedAt)
} catch {
Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference daemon-health observedAt is malformed: '$($inspection.daemonHealth.observedAt)'."
}
$daemonHealthAgeSeconds = ([DateTimeOffset]::UtcNow - $daemonHealthObservedAtUtc.ToUniversalTime()).TotalSeconds
if ($daemonHealthAgeSeconds -gt $MaxWitnessAgeSeconds) {
Fail-IdunnHealth -State "failed" -Message "Nightwing Eve browser reference daemon-health record is stale ($([math]::Round($daemonHealthAgeSeconds))s old)."
}
Write-Host "Nightwing Eve browser reference is active, and its daemon-owned CultCache witness now certifies manifest, boundary, and daemon-health truth directly."

View file

@ -1,3 +0,0 @@
@echo off
echo health-nightwing-eve-dashboard.cmd archived: Nightwing Eve dashboard broker health is not daemon truth. Rebuild typed CultMesh/Odin dashboard state before restoring a health check. 1>&2
exit /b 2

View file

@ -1 +0,0 @@
throw "health-nightwing-eve-dashboard.ps1 archived: Nightwing Eve dashboard broker health is not daemon truth. Inspect typed CultMesh/Odin dashboard state after the publisher is rebuilt."

View file

@ -1,3 +0,0 @@
@echo off
echo health-odin.cmd archived: Odin health is daemon-published over CultNet/RUDP as odin.cultnet-rudp-provider-health. Use health-odin.ps1 only as an explicit daemon witness inspection, not Idunn health truth.
exit /b 2

View file

@ -1,68 +0,0 @@
param(
[string] $StateDir = (Join-Path (Split-Path -Parent $PSScriptRoot) "scratch\odin"),
[int] $MaxSilenceSeconds = 120,
[string] $CultNetRudpBind = "0.0.0.0:17871"
)
$ErrorActionPreference = "Stop"
$pidPath = Join-Path $StateDir "odin.pid"
$outLog = Join-Path $StateDir "odin.out.log"
$errLog = Join-Path $StateDir "odin.err.log"
$cachePath = Join-Path $StateDir "odin.ccmp"
if (-not (Test-Path -LiteralPath $pidPath)) {
throw "Odin PID file is missing at $pidPath"
}
$pidText = (Get-Content -LiteralPath $pidPath -Raw).Trim()
if ($pidText -notmatch '^\d+$') {
throw "Odin PID file is invalid at ${pidPath}: '$pidText'"
}
$process = Get-CimInstance Win32_Process -Filter "ProcessId = $pidText" -ErrorAction SilentlyContinue
if ($null -eq $process) {
throw "Odin process $pidText is not running"
}
foreach ($pattern in @(
'node.exe',
'src\odin-coordinator.cjs',
"--stateDir $StateDir",
"--cultnet-rudp-bind $CultNetRudpBind",
'--idunn-daemon odin',
'--idunn-health-contract odin.cultnet-rudp-provider-health'
)) {
if ($process.CommandLine -notlike "*$pattern*") {
throw "Odin process command line is missing expected segment ${pattern}: $($process.CommandLine)"
}
}
foreach ($logPath in @($outLog, $errLog)) {
if (-not (Test-Path -LiteralPath $logPath)) {
throw "Odin log is missing at $logPath"
}
}
$newestLogWriteUtc = @($outLog, $errLog) |
ForEach-Object { (Get-Item -LiteralPath $_).LastWriteTimeUtc } |
Sort-Object -Descending |
Select-Object -First 1
$logAgeSeconds = ([DateTime]::UtcNow - $newestLogWriteUtc).TotalSeconds
if ($logAgeSeconds -gt $MaxSilenceSeconds) {
throw "Odin logs have been silent for $([math]::Round($logAgeSeconds))s, exceeding $MaxSilenceSeconds seconds"
}
if (-not (Test-Path -LiteralPath $cachePath)) {
throw "Odin CultMesh store is missing at $cachePath"
}
$rudpPort = [int](($CultNetRudpBind -split ':')[-1])
$udpListener = Get-NetUDPEndpoint -LocalPort $rudpPort -ErrorAction SilentlyContinue |
Where-Object { $_.OwningProcess -eq [int]$pidText } |
Select-Object -First 1
if ($null -eq $udpListener) {
throw "Odin is not listening on UDP port $rudpPort as process $pidText"
}
Write-Host "Odin healthy: pid=$pidText cultmesh_rudp_udp=$rudpPort store=$cachePath log_age=$([math]::Round($logAgeSeconds))s"

View file

@ -1,3 +0,0 @@
@echo off
echo health-raven-capture-mux.cmd archived: Raven capture mux no longer owns Muninn daemon health; Muninn publishes muninn.cultnet-rudp-remote-telemetry-health over CultNet/RUDP.
exit /b 2

View file

@ -1,2 +0,0 @@
Write-Error "health-raven-capture-mux.ps1 archived: Raven capture mux no longer owns Muninn daemon health; Muninn publishes muninn.cultnet-rudp-remote-telemetry-health over CultNet/RUDP."
exit 2

View file

@ -1,3 +0,0 @@
@echo off
echo health-stonks.cmd archived: Stonks health is daemon-published over CultNet/RUDP as stonks.cultnet-rudp-market-health. Do not probe localhost HTTP for daemon health. 1>&2
exit /b 2

View file

@ -1,3 +0,0 @@
@echo off
echo health-vili.cmd archived: Vili health is daemon-published over CultNet/RUDP as vili.cultnet-rudp-animation-health. Do not probe HTTP for daemon health. 1>&2
exit /b 2

View file

@ -1,3 +0,0 @@
@echo off
echo health-voidbot.cmd archived: VoidBot health is daemon-published over CultNet/RUDP as voidbot.cultnet-rudp-stack-health. Use health-voidbot.ps1 only as an explicit witness inspection, not Idunn health truth. 1>&2
exit /b 2

View file

@ -1,181 +0,0 @@
param(
[string] $VoidBotRoot = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "VoidBot"),
[int] $MaxOrchestratorAgeSeconds = 180,
[int] $MaxCultMeshStoreAgeSeconds = 180
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
function Fail-IdunnHealth {
param(
[string] $State,
[string] $Message
)
Write-Output "idunn.health.state=$State"
throw $Message
}
function Read-JsonFile {
param([Parameter(Mandatory = $true)][string] $Path)
if (-not (Test-Path -LiteralPath $Path)) {
return $null
}
$raw = Get-Content -LiteralPath $Path -Raw -Encoding UTF8
if ([string]::IsNullOrWhiteSpace($raw)) {
return $null
}
return $raw | ConvertFrom-Json
}
function Get-JsonPropertyValue {
param(
[Parameter(Mandatory = $false)] $Object,
[Parameter(Mandatory = $true)][string] $Name,
[Parameter(Mandatory = $false)] $Default = $null
)
if ($null -eq $Object) {
return $Default
}
$property = $Object.PSObject.Properties[$Name]
if ($null -eq $property) {
return $Default
}
return $property.Value
}
function Get-ProcessOrFail {
param(
[Parameter(Mandatory = $true)][string] $Role,
[Parameter(Mandatory = $true)][int] $ProcessId
)
$process = Get-Process -Id $ProcessId -ErrorAction SilentlyContinue
if ($null -eq $process) {
Fail-IdunnHealth -State "failed" -Message "VoidBot $Role process PID $ProcessId is not running."
}
return $process
}
function Assert-StoreContains {
param(
[Parameter(Mandatory = $true)][string] $StorePath,
[Parameter(Mandatory = $true)][string[]] $Tokens
)
$rg = (Get-Command rg.exe -ErrorAction SilentlyContinue).Source
if ([string]::IsNullOrWhiteSpace($rg)) {
Fail-IdunnHealth -State "degraded" -Message "ripgrep is required to inspect the VoidBot CultMesh witness store."
}
foreach ($token in $Tokens) {
& $rg -a -q --fixed-strings -- $token $StorePath
if ($LASTEXITCODE -ne 0) {
Fail-IdunnHealth -State "degraded" -Message "VoidBot CultMesh witness store is missing '$token'."
}
}
}
$runtimePath = Join-Path $VoidBotRoot ".voidbot\status\runtime-stack.json"
$orchestratorPath = Join-Path $VoidBotRoot ".voidbot\status\gamecult-orchestrator.json"
$cultMeshStorePath = Join-Path $VoidBotRoot ".voidbot\status\cultmesh\voidbot-swarm-state.cc"
$runtime = Read-JsonFile -Path $runtimePath
if ($null -eq $runtime) {
Fail-IdunnHealth -State "failed" -Message "VoidBot runtime state is missing at $runtimePath."
}
if (-not [bool](Get-JsonPropertyValue -Object $runtime -Name "ready" -Default $false)) {
Fail-IdunnHealth -State "failed" -Message "VoidBot runtime stack reports ready=false."
}
$runtimeStage = [string](Get-JsonPropertyValue -Object $runtime -Name "stage" -Default "unknown")
if ($runtimeStage -ne "ready") {
Fail-IdunnHealth -State "failed" -Message "VoidBot runtime stack stage is '$runtimeStage', expected 'ready'."
}
$bot = Get-JsonPropertyValue -Object $runtime -Name "bot"
$worker = Get-JsonPropertyValue -Object $runtime -Name "worker"
$botPid = if ($null -ne $bot) { [int](Get-JsonPropertyValue -Object $bot -Name "pid" -Default 0) } else { 0 }
$workerPid = if ($null -ne $worker) { [int](Get-JsonPropertyValue -Object $worker -Name "pid" -Default 0) } else { 0 }
if ($botPid -le 0) {
Fail-IdunnHealth -State "failed" -Message "VoidBot runtime state does not contain a live bot PID."
}
if ($workerPid -le 0) {
Fail-IdunnHealth -State "failed" -Message "VoidBot runtime state does not contain a live worker PID."
}
$botProcess = Get-ProcessOrFail -Role "bot" -ProcessId $botPid
$workerProcess = Get-ProcessOrFail -Role "worker" -ProcessId $workerPid
$orchestrator = Read-JsonFile -Path $orchestratorPath
if ($null -eq $orchestrator -or $null -eq $orchestrator.organs) {
Fail-IdunnHealth -State "failed" -Message "VoidBot orchestrator state is missing at $orchestratorPath."
}
$surfaceState = $orchestrator.organs.PSObject.Properties["voidbot-swarm-surface"]
if ($null -eq $surfaceState) {
Fail-IdunnHealth -State "failed" -Message "VoidBot orchestrator does not report the voidbot-swarm-surface organ."
}
$surfaceState = $surfaceState.Value
if ($surfaceState.lastStatus -ne "ok") {
Fail-IdunnHealth -State "degraded" -Message "VoidBot swarm surface organ lastStatus is '$($surfaceState.lastStatus)', expected 'ok'."
}
if ([string]::IsNullOrWhiteSpace($surfaceState.lastFinishedAt)) {
Fail-IdunnHealth -State "failed" -Message "VoidBot swarm surface organ has no lastFinishedAt timestamp."
}
$surfaceFinishedAt = [DateTimeOffset]::Parse($surfaceState.lastFinishedAt).ToUniversalTime()
$surfaceAgeSeconds = ([DateTimeOffset]::UtcNow - $surfaceFinishedAt).TotalSeconds
if ($surfaceAgeSeconds -gt $MaxOrchestratorAgeSeconds) {
Fail-IdunnHealth -State "failed" -Message "VoidBot swarm surface organ is stale ($([math]::Round($surfaceAgeSeconds))s old)."
}
$orchestratorFile = Get-Item -LiteralPath $orchestratorPath -ErrorAction SilentlyContinue
if ($null -eq $orchestratorFile) {
Fail-IdunnHealth -State "failed" -Message "VoidBot orchestrator state file is missing at $orchestratorPath."
}
$orchestratorAgeSeconds = ([DateTimeOffset]::UtcNow - [DateTimeOffset]$orchestratorFile.LastWriteTimeUtc).TotalSeconds
if ($orchestratorAgeSeconds -gt $MaxOrchestratorAgeSeconds) {
Fail-IdunnHealth -State "failed" -Message "VoidBot orchestrator state file is stale ($([math]::Round($orchestratorAgeSeconds))s old)."
}
$cultMeshStore = Get-Item -LiteralPath $cultMeshStorePath -ErrorAction SilentlyContinue
if ($null -eq $cultMeshStore) {
Fail-IdunnHealth -State "failed" -Message "VoidBot CultMesh witness store is missing at $cultMeshStorePath."
}
if ($cultMeshStore.Length -le 0) {
Fail-IdunnHealth -State "failed" -Message "VoidBot CultMesh witness store at $cultMeshStorePath is empty."
}
$cultMeshStoreAgeSeconds = ([DateTimeOffset]::UtcNow - [DateTimeOffset]$cultMeshStore.LastWriteTimeUtc).TotalSeconds
if ($cultMeshStoreAgeSeconds -gt $MaxCultMeshStoreAgeSeconds) {
Fail-IdunnHealth -State "failed" -Message "VoidBot CultMesh witness store is stale ($([math]::Round($cultMeshStoreAgeSeconds))s old)."
}
Assert-StoreContains -StorePath $cultMeshStorePath -Tokens @(
"voidbot.provider_advertisement_catalog.v0",
"idunn.command_boundary.v1",
"idunn.daemon_transport_profile.v1",
"voidbot.providers",
"voidbot.discord",
"voidbot.reddit",
"voidbot.archive",
"voidbot.source",
"voidbot.repo_face",
"voidbot.swarm",
"command-boundary:voidbot",
"transport:voidbot"
)
Write-Host "VoidBot runtime is ready, bot PID $($botProcess.Id) and worker PID $($workerProcess.Id) are live, and the daemon-owned CultMesh witness store is fresh."

View file

@ -1,3 +0,0 @@
@echo off
echo health-weksa.cmd archived: Weksa health is daemon-published over CultNet/RUDP as weksa.cultnet-rudp-provider-health. Do not run local command health for daemon truth. 1>&2
exit /b 2

View file

@ -1,3 +0,0 @@
@echo off
echo health-yggdrasil-heimdall.cmd archived: Heimdall health is daemon-published over CultNet/RUDP as heimdall.cultnet-rudp-provider-health. Use health-yggdrasil-source-app.ps1 only as an explicit deployment witness, not Idunn health truth.
exit /b 2

View file

@ -1,3 +0,0 @@
@echo off
echo health-yggdrasil-repixelizer.cmd archived: Repixelizer health is daemon-published over CultNet/RUDP as repixelizer.cultnet-rudp-service-health. Use health-yggdrasil-source-app.ps1 only as an explicit deployment witness, not Idunn health truth.
exit /b 2

View file

@ -1,43 +0,0 @@
param(
[Parameter(Mandatory = $true)] [string] $AppId,
[Parameter(Mandatory = $true)] [string] $RepoRoot,
[Parameter(Mandatory = $true)] [string] $RemoteAppHome,
[Parameter(Mandatory = $true)] [string] $CheckScript,
[string] $SshTarget = "yggdrasil"
)
$ErrorActionPreference = "Stop"
$localCommit = (git -C $RepoRoot rev-parse HEAD).Trim()
if ([string]::IsNullOrWhiteSpace($localCommit)) {
throw "Could not determine git revision for $RepoRoot"
}
$remoteCheck = "/home/gamecultadmin/$([IO.Path]::GetFileName($CheckScript))"
$scpArgs = @("-o", "BatchMode=yes", "-o", "ConnectTimeout=10")
$sshArgs = @("-o", "BatchMode=yes", "-o", "ConnectTimeout=10", $SshTarget)
scp.exe @scpArgs $CheckScript "${SshTarget}:$remoteCheck" | Out-Null
if ($LASTEXITCODE -ne 0) { throw "scp check script failed for $AppId" }
$manifest = ssh.exe @sshArgs "cat '$RemoteAppHome/deployment-manifest.txt' 2>/dev/null"
if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($manifest)) {
throw "$AppId deploy manifest is missing on Yggdrasil."
}
$remoteCommit = ""
foreach ($line in $manifest) {
if ($line -like "gitCommit=*") {
$remoteCommit = $line.Substring("gitCommit=".Length).Trim()
}
}
if ($remoteCommit -ne $localCommit) {
throw "$AppId deploy is stale. remote=$remoteCommit local=$localCommit"
}
ssh.exe @sshArgs "chmod +x '$remoteCheck' && sudo -n bash '$remoteCheck'"
if ($LASTEXITCODE -ne 0) {
throw "$AppId remote health check failed."
}
Write-Host "$AppId is active and deployed at $localCommit."

View file

@ -1,3 +0,0 @@
@echo off
echo health-yggdrasil-streampixels.cmd archived: StreamPixels health is daemon-published over CultNet/RUDP as streampixels.cultnet-rudp-service-health. Use health-yggdrasil-source-app.ps1 only as an explicit deployment witness, not Idunn health truth.
exit /b 2

View file

@ -1,77 +0,0 @@
#!/bin/sh
set -eu
if [ "$(id -u)" -ne 0 ]; then
echo "deploy-yggdrasil-heimdall must run as root through Idunn" >&2
exit 1
fi
source_tar=/srv/heimdall/heimdall-source.tar
cultlib_tar=/srv/heimdall/heimdall-cultlib.tar
releases=/srv/heimdall/app/releases
current=/srv/heimdall/app/current
shared_cultlib="$releases/CultLib"
compose=/srv/compose/yggdrasil-apps.yaml
for required in "$source_tar" "$cultlib_tar" "$compose"; do
if [ ! -f "$required" ]; then
echo "missing audited Heimdall deployment input: $required" >&2
exit 1
fi
done
artifact_sha=$(sha256sum "$source_tar" | awk '{print $1}')
release="$releases/sha-${artifact_sha}"
previous=$(readlink -f "$current" 2>/dev/null || true)
if [ ! -f "$release/.idunn-build-complete" ]; then
staging="$release.staging.$$"
rm -rf "$staging"
install -d -o heimdall -g heimdall "$staging" "$shared_cultlib"
tar -xf "$source_tar" -C "$staging"
rm -rf "$shared_cultlib/packages/cultcache-ts" "$shared_cultlib/packages/cultnet-ts"
tar -xf "$cultlib_tar" -C "$shared_cultlib"
docker run --rm \
-v /srv/heimdall:/srv/heimdall \
-w "$staging" \
node:24.14.1-bookworm-slim@sha256:b506e7321f176aae77317f99d67a24b272c1f09f1d10f1761f2773447d8da26c \
sh -c 'corepack enable && pnpm install --frozen-lockfile && pnpm typecheck && pnpm test && pnpm build && pnpm prune --prod'
printf '%s\n' "$artifact_sha" > "$staging/.idunn-build-complete"
chown -R heimdall:heimdall "$staging" "$shared_cultlib"
mv "$staging" "$release"
fi
ln -sfn "$release" "$current"
chown -h heimdall:heimdall "$current"
if ! docker compose -f "$compose" up -d --force-recreate heimdall; then
if [ -n "$previous" ] && [ -d "$previous" ]; then
ln -sfn "$previous" "$current"
chown -h heimdall:heimdall "$current"
docker compose -f "$compose" up -d --force-recreate heimdall || true
fi
exit 1
fi
healthy=0
for _ in $(seq 1 30); do
if curl -fsS http://127.0.0.1:4100/healthz >/dev/null; then
healthy=1
break
fi
sleep 2
done
if [ "$healthy" -ne 1 ]; then
echo "Heimdall failed health verification after deploying $artifact_sha" >&2
if [ -n "$previous" ] && [ -d "$previous" ]; then
ln -sfn "$previous" "$current"
chown -h heimdall:heimdall "$current"
docker compose -f "$compose" up -d --force-recreate heimdall || true
fi
exit 1
fi
echo "Heimdall deployed audited source artifact $artifact_sha"

View file

@ -1,10 +0,0 @@
@echo off
if not "%IDUNN_ACTUATOR%"=="1" (
echo restart-nightwing-eve-browser-reference.cmd is an Idunn actuator wrapper. Redeploy by poking Idunn; direct service restart is not an owned path. 1>&2
exit /b 1
)
if /I not "%IDUNN_COMMAND_AUTHORITY%"=="idunn-daemon" (
echo restart-nightwing-eve-browser-reference.cmd is an Idunn actuator wrapper. Redeploy by poking Idunn; direct service restart is not an owned path. 1>&2
exit /b 1
)
powershell.exe -NoProfile -ExecutionPolicy Bypass -File %~dp0restart-nightwing-eve-browser-reference.ps1

View file

@ -1,17 +0,0 @@
param(
[string] $SshTarget = "nwroot",
[string] $Service = "nightwing-eve-browser-reference.service"
)
$ErrorActionPreference = "Stop"
if ($env:IDUNN_ACTUATOR -ne "1" -or $env:IDUNN_COMMAND_AUTHORITY -ne "idunn-daemon") {
throw "restart-nightwing-eve-browser-reference.ps1 is an Idunn actuator body. Redeploy by poking Idunn; direct service restart is not an owned path."
}
ssh.exe -o BatchMode=yes -o ConnectTimeout=5 $SshTarget "systemctl restart $Service && systemctl is-active --quiet $Service"
if ($LASTEXITCODE -ne 0) {
throw "Remote restart failed for $Service on $SshTarget with exit code $LASTEXITCODE"
}
Write-Host "Restarted $Service on $SshTarget."

View file

@ -1,3 +0,0 @@
@echo off
echo restart-nightwing-eve-dashboard.cmd archived: Mimir.EveDashboard's HTTP/WebSocket broker is cut. Rebuild a typed CultMesh/Odin dashboard publisher before restoring Idunn lifecycle authority. 1>&2
exit /b 2

View file

@ -1 +0,0 @@
throw "restart-nightwing-eve-dashboard.ps1 archived: Mimir.EveDashboard's HTTP/WebSocket broker is cut. Rebuild a typed CultMesh/Odin dashboard publisher before restoring Idunn lifecycle authority."

View file

@ -1,10 +0,0 @@
@echo off
if not "%IDUNN_ACTUATOR%"=="1" (
echo restart-odin.cmd is an Idunn actuator wrapper. Redeploy by poking Idunn; direct service restart is not an owned path. 1>&2
exit /b 1
)
if /I not "%IDUNN_COMMAND_AUTHORITY%"=="idunn-daemon" (
echo restart-odin.cmd is an Idunn actuator wrapper. Redeploy by poking Idunn; direct service restart is not an owned path. 1>&2
exit /b 1
)
"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -ExecutionPolicy Bypass -File %~dp0restart-odin.ps1

View file

@ -1,46 +0,0 @@
param(
[string] $StateDir = (Join-Path (Split-Path -Parent $PSScriptRoot) "scratch\odin"),
[string] $CultNetRudpBind = "0.0.0.0:17871",
[string] $IdunnRudpHealth = $(if ($env:ODIN_IDUNN_RUDP_HEALTH) { $env:ODIN_IDUNN_RUDP_HEALTH } else { $env:IDUNN_RUDP_HEALTH }),
[string] $IdunnDaemon = "odin",
[string] $IdunnHealthContract = "odin.cultnet-rudp-provider-health"
)
$ErrorActionPreference = "Stop"
if ($env:IDUNN_ACTUATOR -ne "1" -or $env:IDUNN_COMMAND_AUTHORITY -ne "idunn-daemon") {
throw "restart-odin.ps1 is an Idunn actuator body. Redeploy by poking Idunn; direct service restart is not an owned path."
}
$repoRoot = Split-Path -Parent $PSScriptRoot
$stopScript = Join-Path $PSScriptRoot "stop-odin.ps1"
$startScript = Join-Path $PSScriptRoot "start-odin.ps1"
$powerShellExe = Join-Path $env:WINDIR "System32\WindowsPowerShell\v1.0\powershell.exe"
if (-not (Test-Path -LiteralPath $powerShellExe)) {
throw "PowerShell executable is missing at $powerShellExe"
}
$startArgs = @(
"-NoProfile",
"-ExecutionPolicy", "Bypass",
"-File", $startScript,
"-StateDir", $StateDir,
"-CultNetRudpBind", $CultNetRudpBind,
"-IdunnDaemon", $IdunnDaemon,
"-IdunnHealthContract", $IdunnHealthContract
)
if (-not [string]::IsNullOrWhiteSpace($IdunnRudpHealth)) {
$startArgs += @("-IdunnRudpHealth", $IdunnRudpHealth)
}
& $powerShellExe -NoProfile -ExecutionPolicy Bypass -File $stopScript -StateDir $StateDir
if ($LASTEXITCODE -ne 0) {
throw "stop-odin.ps1 failed with exit code $LASTEXITCODE"
}
& $powerShellExe @startArgs
if ($LASTEXITCODE -ne 0) {
throw "start-odin.ps1 failed with exit code $LASTEXITCODE"
}

View file

@ -1,10 +0,0 @@
@echo off
if not "%IDUNN_ACTUATOR%"=="1" (
echo restart-stonks.cmd is an Idunn actuator body. Redeploy by poking Idunn; direct service restart is not an owned path. 1>&2
exit /b 1
)
if /I not "%IDUNN_COMMAND_AUTHORITY%"=="idunn-daemon" (
echo restart-stonks.cmd is an Idunn actuator body. Redeploy by poking Idunn; direct service restart is not an owned path. 1>&2
exit /b 1
)
powershell.exe -NoProfile -ExecutionPolicy Bypass -File %~dp0restart-stonks.ps1

View file

@ -1,21 +0,0 @@
$ErrorActionPreference = "Stop"
$stonksRoot = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "Stonks")
$stateDir = Join-Path $stonksRoot "scratch\stonks"
$pidPath = Join-Path $stateDir "stonks.pid"
$startScript = Join-Path $stonksRoot "scripts\start-stonks.ps1"
if (Test-Path -LiteralPath $pidPath) {
$pidText = (Get-Content -LiteralPath $pidPath -Raw).Trim()
if ($pidText -match "^\d+$") {
$process = Get-Process -Id ([int] $pidText) -ErrorAction SilentlyContinue
if ($null -ne $process) {
Stop-Process -Id $process.Id -Force
Start-Sleep -Milliseconds 500
}
}
Remove-Item -LiteralPath $pidPath -Force -ErrorAction SilentlyContinue
}
& powershell.exe -NoProfile -ExecutionPolicy Bypass -File $startScript
exit $LASTEXITCODE

View file

@ -1,10 +0,0 @@
@echo off
if not "%IDUNN_ACTUATOR%"=="1" (
echo restart-vili.cmd is an Idunn actuator wrapper. Redeploy by poking Idunn; direct service restart is not an owned path. 1>&2
exit /b 1
)
if /I not "%IDUNN_COMMAND_AUTHORITY%"=="idunn-daemon" (
echo restart-vili.cmd is an Idunn actuator wrapper. Redeploy by poking Idunn; direct service restart is not an owned path. 1>&2
exit /b 1
)
powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "%~dp0restart-vili.ps1" %*

View file

@ -1,287 +0,0 @@
param(
[string] $RavenHost = "raven",
[string] $LocalViliRoot = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "Vili"),
[string] $LocalCultLibRoot = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "CultLib"),
[string] $RemoteViliRoot = "E:\Projects\Vili",
[int] $Port = 8824,
[string] $HostName = "0.0.0.0",
[string] $StateRoot = "E:\Projects\Vili\.vili",
[string] $IdunnRudpHealth = $(if ($env:VILI_IDUNN_RUDP_HEALTH) { $env:VILI_IDUNN_RUDP_HEALTH } else { $env:IDUNN_RUDP_HEALTH }),
[string] $IdunnDaemon = "vili",
[string] $IdunnHealthContract = "vili.cultnet-rudp-animation-health",
[int] $IdunnHealthIntervalSeconds = 15
)
$ErrorActionPreference = "Stop"
if ($env:IDUNN_ACTUATOR -ne "1" -or $env:IDUNN_COMMAND_AUTHORITY -ne "idunn-daemon") {
throw "restart-vili.ps1 is an Idunn actuator body. Redeploy by poking Idunn; direct service restart is not an owned path."
}
if ([string]::IsNullOrWhiteSpace($IdunnRudpHealth)) {
throw "Idunn RUDP health endpoint must be supplied by VILI_IDUNN_RUDP_HEALTH, IDUNN_RUDP_HEALTH, or -IdunnRudpHealth; no WireGuard endpoint default is allowed."
}
$localFiles = @(
(Join-Path $LocalViliRoot "package.json"),
(Join-Path $LocalViliRoot "package-lock.json"),
(Join-Path $LocalViliRoot "scripts\idunn-rudp.cjs"),
(Join-Path $LocalViliRoot "scripts\install-vili-task.ps1"),
(Join-Path $LocalViliRoot "scripts\restart-vili-daemon.cmd"),
(Join-Path $LocalViliRoot "scripts\restart-vili-daemon.ps1"),
(Join-Path $LocalViliRoot "scripts\run-hidden-powershell.vbs"),
(Join-Path $LocalViliRoot "scripts\run-vili-daemon.ps1"),
(Join-Path $LocalViliRoot "scripts\start-vili-daemon.ps1"),
(Join-Path $LocalViliRoot "scripts\vili-daemon.mjs"),
(Join-Path $LocalCultLibRoot "packages\cultnet-ts"),
(Join-Path $LocalCultLibRoot "packages\cultcache-ts"),
(Join-Path $LocalCultLibRoot "node_modules\ajv"),
(Join-Path $LocalCultLibRoot "node_modules\fast-deep-equal"),
(Join-Path $LocalCultLibRoot "node_modules\fast-uri"),
(Join-Path $LocalCultLibRoot "node_modules\json-schema-traverse"),
(Join-Path $LocalCultLibRoot "node_modules\require-from-string"),
(Join-Path $LocalViliRoot "node_modules\@msgpack")
)
foreach ($path in $localFiles) {
if (-not (Test-Path -LiteralPath $path)) {
throw "Required Vili runtime path not found: $path"
}
}
$syncId = [guid]::NewGuid().ToString("N")
$remoteSyncRootPs = "$RemoteViliRoot\.odin-vili-sync-$syncId"
$remoteSyncRootSftp = ($remoteSyncRootPs -replace "\\", "/")
$remoteTempPs = "C:\Windows\Temp\odin-raven-vili-restart-$syncId.ps1"
$remoteTempSftp = ($remoteTempPs -replace "\\", "/")
$remoteBundlePs = "C:\Windows\Temp\odin-raven-vili-bundle-$syncId.zip"
$remoteBundleSftp = ($remoteBundlePs -replace "\\", "/")
$localRemoteScript = Join-Path $env:TEMP "odin-raven-vili-restart-$syncId.ps1"
$localSftpBatch = Join-Path $env:TEMP "odin-raven-vili-restart-$syncId.sftp"
$localBundleRoot = Join-Path $env:TEMP "odin-raven-vili-bundle-$syncId"
$localBundleScripts = Join-Path $localBundleRoot "scripts"
$localBundleNodeModules = Join-Path $localBundleRoot "node_modules"
$localBundleZip = Join-Path $env:TEMP "odin-raven-vili-bundle-$syncId.zip"
$remoteScript = @"
`$ErrorActionPreference = "Stop"
`$ProgressPreference = "SilentlyContinue"
`$remoteRoot = "$RemoteViliRoot"
`$syncRoot = "$remoteSyncRootPs"
`$scriptsRoot = Join-Path `$remoteRoot "scripts"
`$stateRoot = "$StateRoot"
`$nodeModulesRoot = Join-Path `$remoteRoot "node_modules"
`$pidPath = Join-Path `$stateRoot "vili-daemon.pid"
try {
Expand-Archive -LiteralPath "$remoteBundlePs" -DestinationPath `$syncRoot -Force
if (-not (Test-Path -LiteralPath `$syncRoot)) {
throw "Uploaded sync root not found at `$syncRoot"
}
if (Test-Path -LiteralPath `$pidPath) {
`$existingPid = (Get-Content -LiteralPath `$pidPath -Raw -ErrorAction SilentlyContinue).Trim()
if (`$existingPid -match '^\d+$') {
`$process = Get-Process -Id ([int] `$existingPid) -ErrorAction SilentlyContinue
if (`$null -ne `$process) {
Stop-Process -Id `$process.Id -Force
Start-Sleep -Seconds 1
}
}
Remove-Item -LiteralPath `$pidPath -Force -ErrorAction SilentlyContinue
}
New-Item -ItemType Directory -Force -Path `$scriptsRoot | Out-Null
New-Item -ItemType Directory -Force -Path `$stateRoot | Out-Null
Copy-Item -LiteralPath (Join-Path `$syncRoot "package.json") -Destination (Join-Path `$remoteRoot "package.json") -Force
Copy-Item -LiteralPath (Join-Path `$syncRoot "package-lock.json") -Destination (Join-Path `$remoteRoot "package-lock.json") -Force
`$scriptFiles = @(
"idunn-rudp.cjs",
"install-vili-task.ps1",
"restart-vili-daemon.cmd",
"restart-vili-daemon.ps1",
"run-hidden-powershell.vbs",
"run-vili-daemon.ps1",
"start-vili-daemon.ps1",
"vili-daemon.mjs"
)
foreach (`$name in `$scriptFiles) {
Copy-Item -LiteralPath (Join-Path `$syncRoot "scripts\`$name") -Destination (Join-Path `$scriptsRoot `$name) -Force
}
if (Test-Path -LiteralPath `$nodeModulesRoot) {
Remove-Item -LiteralPath `$nodeModulesRoot -Recurse -Force
}
Move-Item -LiteralPath (Join-Path `$syncRoot "node_modules") -Destination `$nodeModulesRoot -Force
& powershell.exe @(
"-NoProfile",
"-NonInteractive",
"-ExecutionPolicy", "Bypass",
"-File", (Join-Path `$scriptsRoot "install-vili-task.ps1"),
"-TaskName", "GameCult\Vili",
"-Port", "$Port",
"-HostName", "$HostName",
"-StateRoot", "$StateRoot",
"-IdunnRudpHealth", "$IdunnRudpHealth",
"-IdunnDaemon", "$IdunnDaemon",
"-IdunnHealthContract", "$IdunnHealthContract",
"-IdunnHealthIntervalSeconds", "$IdunnHealthIntervalSeconds"
)
& powershell.exe @(
"-NoProfile",
"-NonInteractive",
"-ExecutionPolicy", "Bypass",
"-File", (Join-Path `$scriptsRoot "restart-vili-daemon.ps1"),
"-Port", "$Port",
"-HostName", "$HostName",
"-StateRoot", "$StateRoot",
"-IdunnRudpHealth", "$IdunnRudpHealth",
"-IdunnDaemon", "$IdunnDaemon",
"-IdunnHealthContract", "$IdunnHealthContract",
"-IdunnHealthIntervalSeconds", "$IdunnHealthIntervalSeconds"
)
`$task = Get-ScheduledTask -TaskName "Vili" -TaskPath "\GameCult\" -ErrorAction Stop
`$action = @(`$task.Actions)[0]
if (`$action.Execute -notmatch '(^|\\)wscript\.exe$') {
throw "GameCult\Vili action executes `$(`$action.Execute), expected wscript.exe"
}
if (`$action.Arguments -notlike "*run-hidden-powershell.vbs*") {
throw "GameCult\Vili action arguments do not reference run-hidden-powershell.vbs"
}
`$taskHealthChecks = @(
(`$action.Arguments -like "*-IdunnRudpHealth*"),
(`$action.Arguments -like "*$IdunnRudpHealth*"),
(`$action.Arguments -like "*-IdunnDaemon*"),
(`$action.Arguments -like "*$IdunnDaemon*"),
(`$action.Arguments -like "*-IdunnHealthContract*"),
(`$action.Arguments -like "*$IdunnHealthContract*")
)
if (`$taskHealthChecks -contains `$false) {
throw "GameCult\Vili action arguments do not carry the Idunn RUDP health contract."
}
`$process = Get-CimInstance Win32_Process |
Where-Object { `$_.CommandLine -like '*vili-daemon.mjs*' } |
Select-Object -First 1
if (`$null -eq `$process) {
throw "Vili process is not running after restart."
}
`$processHealthChecks = @(
(`$process.CommandLine -like "*--idunn-rudp-health*"),
(`$process.CommandLine -like "*$IdunnRudpHealth*"),
(`$process.CommandLine -like "*--idunn-daemon*"),
(`$process.CommandLine -like "*$IdunnDaemon*"),
(`$process.CommandLine -like "*--idunn-health-contract*"),
(`$process.CommandLine -like "*$IdunnHealthContract*")
)
if (`$processHealthChecks -contains `$false) {
throw "Vili process command line does not include the Idunn RUDP health arguments."
}
`$operatorStatePath = Join-Path `$stateRoot "operator-state.json"
`$deadline = (Get-Date).AddSeconds(30)
`$state = `$null
while ((Get-Date) -lt `$deadline) {
if (Test-Path -LiteralPath `$operatorStatePath) {
try {
`$state = Get-Content -LiteralPath `$operatorStatePath -Raw | ConvertFrom-Json
if (`$null -ne `$state.idunnRudpHealth -and `$state.idunnRudpHealth.status -eq "published") {
break
}
} catch {
}
}
Start-Sleep -Seconds 1
}
if (`$null -eq `$state -or `$null -eq `$state.idunnRudpHealth) {
throw "Vili daemon state file did not report idunnRudpHealth after restart."
}
if (`$state.idunnRudpHealth.status -ne "published") {
throw "Vili idunnRudpHealth status is `$(`$state.idunnRudpHealth.status): `$(`$state.idunnRudpHealth.error)"
}
Write-Host "Vili Raven runtime repaired and restarted with Idunn RUDP health."
Write-Host "ProcessId=`$(`$process.ProcessId)"
Write-Host "TaskArguments=`$(`$action.Arguments)"
Write-Host "HealthStatus=`$(`$state.idunnRudpHealth.status)"
Write-Host "HealthContract=`$(`$state.idunnRudpHealth.contract)"
} finally {
Remove-Item -LiteralPath `$syncRoot -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item -LiteralPath "$remoteBundlePs" -Force -ErrorAction SilentlyContinue
}
"@
$batchLines = @(
"put ""$localBundleZip"" ""$remoteBundleSftp""",
"put ""$localRemoteScript"" ""$remoteTempSftp"""
)
try {
$moduleCopies = @(
@{ Source = (Join-Path $LocalCultLibRoot "packages\cultnet-ts"); Destination = (Join-Path $localBundleNodeModules "cultnet-ts") },
@{ Source = (Join-Path $LocalCultLibRoot "packages\cultcache-ts"); Destination = (Join-Path $localBundleNodeModules "cultcache-ts") },
@{ Source = (Join-Path $LocalCultLibRoot "node_modules\ajv"); Destination = (Join-Path $localBundleNodeModules "ajv") },
@{ Source = (Join-Path $LocalCultLibRoot "node_modules\fast-deep-equal"); Destination = (Join-Path $localBundleNodeModules "fast-deep-equal") },
@{ Source = (Join-Path $LocalCultLibRoot "node_modules\fast-uri"); Destination = (Join-Path $localBundleNodeModules "fast-uri") },
@{ Source = (Join-Path $LocalCultLibRoot "node_modules\json-schema-traverse"); Destination = (Join-Path $localBundleNodeModules "json-schema-traverse") },
@{ Source = (Join-Path $LocalCultLibRoot "node_modules\require-from-string"); Destination = (Join-Path $localBundleNodeModules "require-from-string") },
@{ Source = (Join-Path $LocalViliRoot "node_modules\@msgpack"); Destination = (Join-Path $localBundleNodeModules "@msgpack") }
)
New-Item -ItemType Directory -Force -Path $localBundleScripts, $localBundleNodeModules | Out-Null
Copy-Item -LiteralPath (Join-Path $LocalViliRoot "package.json") -Destination (Join-Path $localBundleRoot "package.json") -Force
Copy-Item -LiteralPath (Join-Path $LocalViliRoot "package-lock.json") -Destination (Join-Path $localBundleRoot "package-lock.json") -Force
$scriptCopies = @(
"idunn-rudp.cjs",
"install-vili-task.ps1",
"restart-vili-daemon.cmd",
"restart-vili-daemon.ps1",
"run-hidden-powershell.vbs",
"run-vili-daemon.ps1",
"start-vili-daemon.ps1",
"vili-daemon.mjs"
)
foreach ($scriptName in $scriptCopies) {
Copy-Item -LiteralPath (Join-Path $LocalViliRoot "scripts\$scriptName") -Destination (Join-Path $localBundleScripts $scriptName) -Force
}
foreach ($copy in $moduleCopies) {
New-Item -ItemType Directory -Force -Path (Split-Path -Parent $copy.Destination) | Out-Null
Copy-Item -LiteralPath $copy.Source -Destination $copy.Destination -Recurse -Force
}
if (Test-Path -LiteralPath $localBundleZip) {
Remove-Item -LiteralPath $localBundleZip -Force
}
Compress-Archive -Path (Join-Path $localBundleRoot "*") -DestinationPath $localBundleZip -CompressionLevel Optimal
Set-Content -LiteralPath $localRemoteScript -Encoding ASCII -Value $remoteScript
Set-Content -LiteralPath $localSftpBatch -Encoding ASCII -Value ($batchLines -join "`r`n")
& sftp.exe -b $localSftpBatch $RavenHost
if ($LASTEXITCODE -ne 0) {
exit $LASTEXITCODE
}
$remoteRunner = @"
`$ErrorActionPreference = "Stop"
try {
& "$remoteTempPs"
`$code = `$LASTEXITCODE
} finally {
Remove-Item -LiteralPath "$remoteTempPs" -Force -ErrorAction SilentlyContinue
}
exit `$code
"@
$encodedRunner = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($remoteRunner))
& ssh.exe -o BatchMode=yes -o ConnectTimeout=10 $RavenHost "powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -EncodedCommand $encodedRunner"
} finally {
Remove-Item -LiteralPath $localRemoteScript, $localSftpBatch -Force -ErrorAction SilentlyContinue
Remove-Item -LiteralPath $localBundleZip -Force -ErrorAction SilentlyContinue
Remove-Item -LiteralPath $localBundleRoot -Recurse -Force -ErrorAction SilentlyContinue
}
$restartExit = $LASTEXITCODE
exit $restartExit

View file

@ -1,10 +0,0 @@
@echo off
if not "%IDUNN_ACTUATOR%"=="1" (
echo restart-weksa.cmd is an Idunn actuator body. Redeploy by poking Idunn; direct service restart is not an owned path. 1>&2
exit /b 1
)
if /I not "%IDUNN_COMMAND_AUTHORITY%"=="idunn-daemon" (
echo restart-weksa.cmd is an Idunn actuator body. Redeploy by poking Idunn; direct service restart is not an owned path. 1>&2
exit /b 1
)
call %~dp0..\..\weksa\scripts\restart-weksa-daemon.cmd

View file

@ -1,68 +0,0 @@
param(
[string] $StateDir = (Join-Path (Split-Path -Parent $PSScriptRoot) "scratch\odin"),
[string] $CultNetRudpBind = "0.0.0.0:17871",
[string] $IdunnRudpHealth = $(if ($env:ODIN_IDUNN_RUDP_HEALTH) { $env:ODIN_IDUNN_RUDP_HEALTH } else { $env:IDUNN_RUDP_HEALTH }),
[string] $IdunnDaemon = "odin",
[string] $IdunnHealthContract = "odin.cultnet-rudp-provider-health",
[switch] $Foreground
)
$ErrorActionPreference = "Stop"
$repoRoot = Split-Path -Parent $PSScriptRoot
$scriptPath = Join-Path $repoRoot "src\odin-coordinator.cjs"
$pidPath = Join-Path $StateDir "odin.pid"
$outLog = Join-Path $StateDir "odin.out.log"
$errLog = Join-Path $StateDir "odin.err.log"
$nodeExe = (Get-Command node.exe -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty Source)
if (-not $nodeExe) {
$nodeExe = "C:\Program Files\nodejs\node.exe"
}
if (-not (Test-Path -LiteralPath $nodeExe)) {
throw "Node.js executable is missing; checked PATH and $nodeExe"
}
if ([string]::IsNullOrWhiteSpace($IdunnRudpHealth)) {
throw "Odin Idunn health publication requires -IdunnRudpHealth, ODIN_IDUNN_RUDP_HEALTH, or IDUNN_RUDP_HEALTH; no localhost default is assumed."
}
New-Item -ItemType Directory -Force -Path $StateDir | Out-Null
if (Test-Path $pidPath) {
$oldPid = (Get-Content -Raw $pidPath).Trim()
if ($oldPid -match "^\d+$") {
$old = Get-Process -Id ([int] $oldPid) -ErrorAction SilentlyContinue
if ($old) {
throw "Odin already appears to be running as PID $oldPid."
}
}
Remove-Item -LiteralPath $pidPath -Force
}
$env:NODE_PATH = (Join-Path (Split-Path -Parent (Split-Path -Parent $PSScriptRoot)) "CultLib\packages")
$args = @(
$scriptPath,
"--stateDir", $StateDir,
"--cultnet-rudp-bind", $CultNetRudpBind,
"--idunn-rudp-health", $IdunnRudpHealth,
"--idunn-daemon", $IdunnDaemon,
"--idunn-health-contract", $IdunnHealthContract
)
if ($Foreground) {
& $nodeExe @args
exit $LASTEXITCODE
}
$proc = Start-Process -FilePath $nodeExe -ArgumentList $args -WorkingDirectory $repoRoot -WindowStyle Hidden -PassThru -RedirectStandardOutput $outLog -RedirectStandardError $errLog
$proc.Id | Set-Content -Encoding ASCII -LiteralPath $pidPath
Start-Sleep -Seconds 1
if ($proc.HasExited) {
$detail = ""
if (Test-Path $outLog) { $detail += Get-Content -Raw $outLog }
if (Test-Path $errLog) { $detail += Get-Content -Raw $errLog }
throw "Odin exited immediately with code $($proc.ExitCode).`n$detail"
}
Write-Host "Odin started as PID $($proc.Id)."
Write-Host "CultMesh/RUDP document catalog: $CultNetRudpBind"

View file

@ -1,22 +0,0 @@
param(
[string] $StateDir = (Join-Path (Split-Path -Parent $PSScriptRoot) "scratch\odin")
)
$ErrorActionPreference = "Stop"
$pidPath = Join-Path $StateDir "odin.pid"
if (-not (Test-Path $pidPath)) {
Write-Host "No Odin PID file found at $pidPath."
exit 0
}
$odinPid = (Get-Content -Raw $pidPath).Trim()
if ($odinPid -match "^\d+$") {
$process = Get-Process -Id ([int] $odinPid) -ErrorAction SilentlyContinue
if ($process) {
Stop-Process -Id $process.Id
Write-Host "Stopped Odin PID $odinPid."
}
}
Remove-Item -LiteralPath $pidPath -Force