$ErrorActionPreference = "Stop" $installer = Join-Path (Split-Path $PSScriptRoot -Parent) "install.ps1" $tokens = $null $parseErrors = $null [System.Management.Automation.Language.Parser]::ParseFile( $installer, [ref]$tokens, [ref]$parseErrors ) | Out-Null if ($parseErrors.Count -gt 0) { throw "install.ps1 parser errors: $($parseErrors.Message -join '; ')" } $source = Get-Content -LiteralPath $installer -Raw function Assert-SourceContains { param([Parameter(Mandatory)][string]$Pattern, [Parameter(Mandatory)][string]$Message) if ($source -notmatch $Pattern) { throw $Message } } $runtimeMatch = [regex]::Match( $source, '(?s)\$RuntimeFiles\s*=\s*@\((?.*?)\)' ) if (!$runtimeMatch.Success) { throw "Runtime file allowlist was not found." } $runtimeFiles = $runtimeMatch.Groups["files"].Value foreach ($forbidden in @("agent-config.json", "agent-state.json", "logs", "backups")) { if ($runtimeFiles -match [regex]::Escape($forbidden)) { throw "$forbidden must not be a managed deployment target." } } $preflight = $source.IndexOf('# Validate the complete source') $firstTargetChange = $source.IndexOf('New-Item -ItemType Directory') if ($preflight -lt 0 -or $preflight -gt $firstTargetChange) { throw "Source preflight must happen before target changes." } Assert-SourceContains 'if \(\$null -ne \(Get-MinerOpsScheduledTask' ` "Existing task preservation guard is missing." Assert-SourceContains 'Preserving existing Scheduled Task' ` "Existing task preservation is not explicit." Assert-SourceContains 'ExtraArguments\s*=\s*"-Limit 0 -TimeoutMs 8000"' ` "Fresh enrichment task arguments are missing." Assert-SourceContains 'Stop-MinerOpsScheduledTaskForUpgrade' ` "Bounded main Agent stop behavior is missing." Assert-SourceContains '\$mainTaskWasRunning' ` "Main Agent prior running state is not represented." Assert-SourceContains 'Copy-Item[^\r\n]*\(Join-Path \$Backup \$name\)' ` "Rollback does not restore managed files from backup." Assert-SourceContains 'Unregister-ScheduledTask' ` "Rollback does not remove tasks created by a failed install." Assert-SourceContains 'could not restart restored MinerOpsAgent' ` "Rollback restart failure is not surfaced." if ($source -match 'Register-ScheduledTask[^\r\n]*-Force') { throw "Installer must not force-overwrite Scheduled Tasks." } if ($source -match '(?i)agent_secret|api3_password|api3_account') { throw "Installer must not inspect or print credentials." } Write-Host "MinerOps installer source safety tests passed."