# Windows Verification Runner

This runner lets Linux/Codex submit Windows verification jobs without keeping a long SSH or WinRM command attached to the test process.

## Layout

The default root is `C:\llm-wiki-runner`:

```text
C:\llm-wiki-runner\
  queue\
  running\
  done\
  failed\
  logs\
  scripts\
  runner.ps1
```

## Install On Windows

Run from an elevated PowerShell prompt if the task should be available machine-wide:

```powershell
Set-Location <llm-wiki-kit>\scripts\windows-runner
.\install-scheduled-task.ps1 -Root C:\llm-wiki-runner
```

PowerShell 7 (`pwsh.exe`) is required. Installation fails before registering or copying runner state when only Windows PowerShell 5.1 is available, because reliable timeout handling requires descendant process-tree termination.

The scheduled task is named `LlmWikiWindowsRunner` by default. It has no repeating trigger, so it does not wake up while the Windows PC is being used normally. It runs one queued job when triggered manually and uses hidden PowerShell/task settings so verification windows are not shown.

You can trigger it immediately after submitting a job:

```powershell
Start-ScheduledTask -TaskName LlmWikiWindowsRunner
```

If a polling runner is explicitly needed, install with `-EnablePolling -IntervalMinutes <minutes>`. Do not use polling on a desktop where background command windows or periodic wakeups are unwanted.

## Job Format

Write a JSON file to `queue\<id>.json`. The `id` must match the filename without `.json`.

```json
{
  "id": "20260620-001",
  "command": "pwsh",
  "args": ["-NoProfile", "-File", "C:\\llm-wiki-runner\\scripts\\verify.ps1"],
  "cwd": "C:\\work\\llm-wiki-kit",
  "timeout_seconds": 900
}
```

The runner writes:

- `logs\<id>.status.json`
- `logs\<id>.stdout.log`
- `logs\<id>.stderr.log`

Final states are `succeeded`, `failed`, or `timed_out`.

## Submit From Linux

Use SSH/scp for normal submission and observation:

```bash
scp job.json windows-host:/C:/llm-wiki-runner/queue/20260620-001.json
ssh windows-host 'powershell -NoProfile -Command "Start-ScheduledTask -TaskName LlmWikiWindowsRunner"'
ssh windows-host 'powershell -NoProfile -Command "Get-Content C:\llm-wiki-runner\logs\20260620-001.status.json"'
```

WinRM should be kept as a bootstrap or emergency recovery fallback only, for example when SSH or the scheduled task is unavailable.

Do not put credentials, tokens, private keys, or raw `.env` contents in job JSON. If a verification needs secrets, use the Windows account's existing secret store and keep job files limited to script names and safe arguments.

## Release Contract Verification

`verify-release.ps1` runs the same source gates used by CI on a native Windows host and emits a compact JSON result containing stage names, status, and timings only. Child stdout/stderr is captured in memory and discarded on success or failure; it is never copied into the summary or runner logs. Each child stage is bounded by `-StageTimeoutSeconds` (default 900), and tarball mode isolates npm cache and user config as well as provider homes.

```powershell
pwsh -NoProfile -File .\verify-release.ps1 -Mode Source -SourceRoot C:\work\llm-wiki-kit -OutputPath C:\llm-wiki-runner\logs\release-source.json
```

After `npm pack`, verify the exact tarball in an isolated home and install prefix:

```powershell
pwsh -NoProfile -File .\verify-release.ps1 -Mode Tarball -PackageSpec C:\work\llm-wiki-kit\llm-wiki-kit-<version>.tgz -ExpectedVersion <version> -OutputPath C:\llm-wiki-runner\logs\release-tarball.json
```

The tarball mode does not reuse the developer's provider homes. It verifies install/version, current hooks/skills/templates, lint, a synthetic strict eval, memory health, required doctor checks, and the packaged state/concurrency/atomic-replace tests from a temporary isolated environment. The temporary environment is removed afterward. Missing external `codex`/`claude` executables are reported by doctor but are not part of the isolated package gate; hook and skill installation for both providers is required.
