// node --test relay/test/service.test.mjs The relay agent as a logon task and the start-app kind (MF-11, 7 October // 2026). Structural checks of the manifest, the installer, the hidden loop, the agent's branch and the Mac tool; the // PowerShell 5.1 parse of the .ps1 files is windows.yml's job. import { test } from 'node:test'; import assert from 'node:assert/strict'; import { readFileSync } from 'node:fs'; import { join, dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; import { KINDS, AGENT_KINDS } from '../lib/relay.mjs'; const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..', '..'); const read = p => readFileSync(join(ROOT, p), 'utf8'); test('the service manifest: at logon, the run level the installer chooses, interactive, restarted on failure, no time limit, one instance, hidden window', () => { const x = read('relay/clients/IgneumRelayService.xml'); assert.match(x, /[\s\S]*__USER__<\/UserId>[\s\S]*<\/LogonTrigger>/); assert.match(x, /[\s\S]*__USER__<\/UserId>[\s\S]*InteractiveToken<\/LogonType>[\s\S]*__RUNLEVEL__<\/RunLevel>/); const restart = /\s*PT(\d+)M<\/Interval>\s*(\d+)<\/Count>\s*<\/RestartOnFailure>/.exec(x); assert.ok(restart, 'RestartOnFailure with Interval and Count'); assert.ok(Number(restart[1]) <= 5 && Number(restart[2]) >= 100, `restart every ${restart[1]} min, ${restart[2]} times`); assert.match(x, /PT0S<\/ExecutionTimeLimit>/, 'no time limit'); assert.match(x, /IgnoreNew<\/MultipleInstancesPolicy>/); assert.match(x, /false<\/DisallowStartIfOnBatteries>/); assert.match(x, /false<\/StopIfGoingOnBatteries>/); assert.match(x, /true<\/StartWhenAvailable>/); assert.match(x, /powershell\.exe<\/Command>\s*-NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File "__AGENT_DIR__\\igneum-agent-service\.ps1"<\/Arguments>/); assert.match(x, /\\IgneumRelayService<\/URI>/); }); test('the installer fills the manifest and registers, runs and reads back the task; it carries no secret', () => { const s = read('relay/clients/install-agent.ps1'); assert.doesNotMatch(s, /#Requires -RunAsAdministrator/, 'a per-user task needs no administrator (PC 2 has nobody to click a prompt)'); assert.match(s, /\.Replace\('__RUNLEVEL__', \$level\)/); assert.match(s, /\$level = 'LeastPrivilege'[\s\S]*if \(\$Highest\) \{ \$level = 'HighestAvailable' \}/); // the stale one-shot tasks (PC 2, 7 October 2026: a logon task at a path that was not there popped a dialog at every boot) go first assert.match(s, /IgneumRelayAgent\*/); assert.match(s, /schtasks\.exe \/Delete \/F \/TN \$t/); assert.match(s, /RunOnce/); assert.match(s, /\.Replace\('__USER__', \$user\)\.Replace\('__AGENT_DIR__', \$Here\)/); assert.match(s, /schtasks\.exe \/Create \/F \/TN \$TaskName \/XML \$tmp/); assert.match(s, /\$TaskName = 'IgneumRelayService'/); assert.match(s, /schtasks\.exe \/Run \/TN \$TaskName/); assert.match(s, /schtasks\.exe \/Query \/TN \$TaskName/); assert.match(s, /machine-secret\.txt/, 'the zip must carry the machine secret for the agent to run anything'); assert.doesNotMatch(s, /__RELAY_(URL|KEY|TOKEN)__|x-relay-token|x-igneum-key/, 'the installer touches no secret'); assert.match(s, /-Remove/); }); test('the hidden loop keeps the agent running for ever, 15 s after any exit, logs without the idle line, and a missing agent path is a log line, never a dialog', () => { const s = read('relay/clients/igneum-agent-service.ps1'); // the task runs the loop by its full path under -WindowStyle Hidden (the manifest), and the loop itself opens nothing: // a missing igneum-agent.ps1 is one line in the log and a 60 s wait, no `cmd /c start`, no message box, no exit const missing = s.slice(s.indexOf('if (-not (Test-Path $Agent))'), s.indexOf('Note \'starting igneum-agent.ps1\'')); assert.match(missing, /Note \('no agent at ' \+ \$Agent \+ '; waiting'\); Start-Sleep -Seconds 60; continue/); assert.doesNotMatch(s, /cmd(\.exe)? \/c start|MessageBox|Read-Host|\[System\.Windows\.Forms/); assert.match(s, /-File \$Agent/, 'the agent runs by its full path'); assert.match(s, /ForEach-Object \{ Add-Content -Path \$log -Value \$_ \}/, 'one write per line: the log is never held open'); assert.match(s, /\$Agent = Join-Path \$Here 'igneum-agent\.ps1'/); assert.match(s, /while \(\$true\) \{/); assert.match(s, /powershell\.exe -NoProfile -ExecutionPolicy Bypass -File \$Agent/); assert.match(s, /Start-Sleep -Seconds 15/); assert.match(s, /-notmatch 'idle as '/); assert.match(s, /agent-service\.log/); assert.doesNotMatch(s, /api\/(quit|pause|resume)/); }); test('the agent runs a start-app task through its own Start-App after the tag check, never the body, never elevated, never a quit', () => { const s = read('relay/clients/igneum-agent.ps1'); const run = s.slice(s.indexOf('function Run-Task'), s.indexOf('Log ("igneum relay agent on')); const check = run.indexOf('$why = Check-Task $task'); const nonce = run.indexOf('Add-Content -Path $NonceFile -Value $task.flags.nonce'); const branch = run.indexOf("if (\"$($task.kind)\" -eq 'start-app') {"); const script = run.indexOf('[IO.File]::WriteAllText($script'); assert.ok(check > 0 && nonce > check && branch > nonce && script > branch, 'tag check, nonce recorded, the start-app branch, and only then a script is written'); assert.match(run, /\$r = Start-App[\s\S]*Post-Result \$task \(\[int\]\$r\.code\) \$log \$r\.note[\s\S]*return\s*\}/); const start = s.slice(s.indexOf('function Start-App'), s.indexOf('function Sha256-Hex')); assert.match(start, /\/RL LIMITED/, 'an elevated agent starts the app at the limited run level'); assert.match(start, /Start-Process -FilePath \$exe -ArgumentList '--launch'/); assert.match(start, /api\/state/); assert.doesNotMatch(start, /api\/(quit|pause|resume|cards)/); assert.doesNotMatch(start, /\$task\.body|Invoke-Expression/); assert.match(s, /agent = 'igneum-agent\.ps1 v3'/); // the registration carries the app's per-install id, so two PCs with one Windows hostname are two machines assert.match(s, /Api-Post 'register' @\{ hostname = \(Machine-Hostname\); info = \$info \}/); assert.match(s, /igneum\\app\\machine-id/); assert.match(s, /\$id\.Substring\(0, 8\)/); // the one-shot reboot arm is still the only task the agent removes: the service task is never touched const disarm = s.slice(s.indexOf('function Disarm-Restart'), s.indexOf('function Sha256-Hex')); assert.doesNotMatch(disarm, /IgneumRelayService/); assert.match(disarm, /schtasks\.exe \/Delete \/F \/TN 'IgneumRelayAgent'/); }); test('the start-app body for older agents does the same thing and never quits the installed app', () => { const s = read('relay/playbooks/start-app.ps1'); assert.match(s, /api\/state/); assert.match(s, /\/RL LIMITED/); assert.doesNotMatch(s, /api\/(quit|pause|resume|cards)/); assert.doesNotMatch(s, /__DL_BASE__/); }); test('the kind is known to the relay, the Mac tool signs it, and the zip carries the service files', () => { assert.ok(KINDS.has('start-app')); assert.deepEqual(AGENT_KINDS, ['run', 'start-app']); const m = read('tools/relay.mjs'); assert.match(m, /cmd === 'start-app'/); assert.match(m, /kind: 'start-app', body, flags: \{ elevated: false/); const sa = m.slice(m.indexOf("cmd === 'start-app'"), m.indexOf("cmd === 'keygen'")); assert.match(sa, /signRunTask\(o\)/, 'start-app is signed and tagged like run'); assert.match(sa, /'start-app\.ps1'\)/); const mk = read('relay/clients/make-clients.sh'); for (const f of ['igneum-agent-service.ps1', 'install-agent.ps1', 'IgneumRelayService.xml']) assert.match(mk, new RegExp(f.replace('.', '\\.')), `${f} is not in the zip`); });