$ErrorActionPreference = "Stop" Set-StrictMode -Version Latest $repo = (Resolve-Path -LiteralPath (Join-Path $PSScriptRoot "..")).Path $validator = Join-Path $repo "scripts\validate-n12r-return-package.ps1" $tempRoot = Join-Path ([System.IO.Path]::GetTempPath()) ("n12r-validator-tests-" + [guid]::NewGuid().ToString("N")) function Assert-True([bool]$Condition, [string]$Message) { if (-not $Condition) { throw $Message } } function Assert-Contains([string]$Haystack, [string]$Needle, [string]$Message) { if ($Haystack -notlike "*$Needle*") { throw "$Message`nExpected to contain: $Needle`nActual: $Haystack" } } function Write-Utf8Text([string]$Path, [string]$Content) { $parent = Split-Path -Parent $Path if ($parent -and -not (Test-Path -LiteralPath $parent)) { New-Item -ItemType Directory -Force -Path $parent | Out-Null } Set-Content -LiteralPath $Path -Value $Content -Encoding UTF8 } function Write-Json([string]$Path, [object]$Value) { Write-Utf8Text -Path $Path -Content ($Value | ConvertTo-Json -Depth 32) } function New-GoodPackage([string]$Path) { New-Item -ItemType Directory -Force -Path $Path | Out-Null foreach ($dir in @("metadata", "helper", "windows", "uia", "notes")) { New-Item -ItemType Directory -Force -Path (Join-Path $Path $dir) | Out-Null } Write-Utf8Text (Join-Path $Path "metadata\source-notes.txt") @" Capture source: internal-network test sandbox. Login method: human operator completed normal interactive sign-in. Boundary: read-only UI Automation capture only. "@ Write-Utf8Text (Join-Path $Path "metadata\os-version.txt") "Microsoft Windows test sandbox" Write-Utf8Text (Join-Path $Path "metadata\process-list.txt") "IMPlatformClient 4242" Write-Utf8Text (Join-Path $Path "metadata\repo-status.txt") "## main...origin/main" Write-Utf8Text (Join-Path $Path "metadata\verification-summary.txt") "N12R package files present." Write-Json (Join-Path $Path "helper\version.json") @{ ok = $true data = @{ helper_name = "ISphereWinHelper" helper_version = "0.1.0" } } Write-Json (Join-Path $Path "helper\self-check.json") @{ ok = $true data = @{ desktop_available = $true uia_available = $true } } Write-Json (Join-Path $Path "windows\scan-windows.json") @{ ok = $true data = @{ windows = @( @{ hwnd = "0x123456" title = "iSphere - Test Sandbox" process_name = "IMPlatformClient" process_id = 4242 class_name = "WindowsForms10.Window.8.app.0" } ) } } Write-Json (Join-Path $Path "windows\selected-window.json") @{ hwnd = "0x123456" title = "iSphere - Test Sandbox" process_name = "IMPlatformClient" process_id = 4242 } $uiaTree = @{ ok = $true data = @{ root = @{ name = "iSphere - Test Sandbox" control_type = "Window" automation_id = "MainWindow" children = @( @{ name = "Conversation list" control_type = "List" children = @() } ) } } } Write-Json (Join-Path $Path "uia\dump-uia-main.json") $uiaTree Write-Json (Join-Path $Path "uia\dump-uia-main-redacted.json") $uiaTree Write-Utf8Text (Join-Path $Path "notes\operator-notes.txt") "Read-only capture. No message/file action was performed." } function Invoke-Validator([string]$PackageRoot, [string]$ReportPath) { $output = & powershell -NoProfile -ExecutionPolicy Bypass -File $validator -PackageRoot $PackageRoot -ReportPath $ReportPath 2>&1 [pscustomobject]@{ ExitCode = $LASTEXITCODE Output = ($output | Out-String) } } function Run-Test([string]$Name, [scriptblock]$Body) { Write-Host "## $Name" & $Body Write-Host "PASS $Name" } try { New-Item -ItemType Directory -Force -Path $tempRoot | Out-Null Run-Test "accepts a complete read-only N12R package" { $pkg = Join-Path $tempRoot "good" $report = Join-Path $tempRoot "good-report.md" New-GoodPackage $pkg $result = Invoke-Validator -PackageRoot $pkg -ReportPath $report Assert-True ($result.ExitCode -eq 0) "Expected validator success, got exit $($result.ExitCode): $($result.Output)" Assert-Contains $result.Output "Decision: ACCEPT" "Expected accept decision in output." Assert-True (Test-Path -LiteralPath $report) "Expected markdown report to be written outside package root." Assert-Contains (Get-Content -LiteralPath $report -Raw -Encoding UTF8) "Decision: ACCEPT" "Expected accept decision in report." } Run-Test "rejects a package missing the redacted UIA dump" { $pkg = Join-Path $tempRoot "missing-redacted" $report = Join-Path $tempRoot "missing-redacted-report.md" New-GoodPackage $pkg Remove-Item -LiteralPath (Join-Path $pkg "uia\dump-uia-main-redacted.json") -Force $result = Invoke-Validator -PackageRoot $pkg -ReportPath $report Assert-True ($result.ExitCode -ne 0) "Expected validator failure for missing redacted UIA dump." Assert-Contains $result.Output "uia/dump-uia-main-redacted.json" "Expected missing required path in output." Assert-Contains $result.Output "Decision: REJECT" "Expected reject decision in output." } Run-Test "rejects malformed required JSON" { $pkg = Join-Path $tempRoot "bad-json" $report = Join-Path $tempRoot "bad-json-report.md" New-GoodPackage $pkg Write-Utf8Text (Join-Path $pkg "helper\version.json") "{not-json" $result = Invoke-Validator -PackageRoot $pkg -ReportPath $report Assert-True ($result.ExitCode -ne 0) "Expected validator failure for malformed JSON." Assert-Contains $result.Output "helper/version.json" "Expected malformed JSON path in output." Assert-Contains $result.Output "JSON parse failed" "Expected JSON parse failure message." } Run-Test "rejects obvious forbidden action evidence" { $pkg = Join-Path $tempRoot "forbidden-action" $report = Join-Path $tempRoot "forbidden-action-report.md" New-GoodPackage $pkg Write-Utf8Text (Join-Path $pkg "notes\operator-notes.txt") "operator accidentally ran send_message during capture" $result = Invoke-Validator -PackageRoot $pkg -ReportPath $report Assert-True ($result.ExitCode -ne 0) "Expected validator failure for forbidden action evidence." Assert-Contains $result.Output "send_message" "Expected forbidden action token in output." Assert-Contains $result.Output "Decision: REJECT" "Expected reject decision in output." } Run-Test "rejects report paths inside the evidence package" { $pkg = Join-Path $tempRoot "report-inside-package" New-GoodPackage $pkg $report = Join-Path $pkg "validation-report.md" $result = Invoke-Validator -PackageRoot $pkg -ReportPath $report Assert-True ($result.ExitCode -ne 0) "Expected validator failure when report path is inside package root." Assert-Contains $result.Output "ReportPath must be outside PackageRoot" "Expected package immutability error." Assert-True (-not (Test-Path -LiteralPath $report)) "Validator must not write a report inside the package root." } } finally { if (Test-Path -LiteralPath $tempRoot) { Remove-Item -LiteralPath $tempRoot -Recurse -Force } }