param([string]$AgentRoot = (Join-Path $PSScriptRoot '..')) $ErrorActionPreference = 'Stop' $checks=0 foreach ($file in @('MinerOpsAgentService.ps1','EnrichOneMiner.ps1','MinerOpsApi3EnrichmentPoller.ps1','MinerOpsPoolPoller.ps1')) { $tokens=$null; $errors=$null $ast=[System.Management.Automation.Language.Parser]::ParseFile((Join-Path $AgentRoot $file),[ref]$tokens,[ref]$errors) if ($errors.Count) { throw "Parse errors in ${file}: $errors" } $checks++ if ($file -eq 'MinerOpsAgentService.ps1') { $function=$ast.Find({param($n) $n -is [System.Management.Automation.Language.FunctionDefinitionAst] -and $n.Name -eq 'Invoke-AgentApi'},$true) Invoke-Expression $function.Extent.Text } } function Read-AgentConfig { return @{hub_url='https://hub.invalid';agent_id='simulated-agent';agent_secret='disposable-only'} } $script:requests=@() function Invoke-RestMethod { param($Method,$Uri,$Headers,$ContentType,$Body,$TimeoutSec) $parsed=$Body | ConvertFrom-Json $script:requests+=@{body=$parsed;headers=$Headers} return @{ok=$true} } foreach ($selection in @(@{path='/api/agent/discoveries';field='discoveries'},@{path='/api/agent/miner-snapshots';field='miners'})) { $script:requests=@();$body=@{agent_id='simulated-agent'} $body[$selection.field]=@(1..257 | ForEach-Object { @{sample=$_;miner_version='signed-version'} }) $result=Invoke-AgentApi -Method POST -Path $selection.path -Body $body $sizes=@($script:requests | ForEach-Object { @($_.body.($selection.field)).Count }) if (($sizes -join ',') -ne '128,128,1') { throw "Unsafe batching: $sizes" } foreach ($request in $script:requests) { if ($request.headers['X-MinerOps-Agent-ID'] -ne 'simulated-agent') { throw 'Identity lost' } } if ($result.processed -ne 257) { throw 'Samples lost' } $checks+=3 } # Execute the actual target-validation prefix only; transport functions/loops are never loaded. $source=Get-Content -LiteralPath (Join-Path $AgentRoot 'EnrichOneMiner.ps1') -Raw $start=$source.IndexOf('$config = Read-AgentConfig') $finish=$source.IndexOf('$commands = @(',$start) $prefix=$source.Substring($start,$finish-$start) $script:targetRequests=0 function Invoke-RestMethod { param($Method,$Uri,$Headers,$ContentType,$Body) $script:targetRequests++ if ($Uri -notlike '*/api/agent/discovery-target') { throw 'Unexpected request' } return @{ok=$true;ip_address='198.51.100.10'} } $DiscoveryId='';$ObservationVersion='';$CommandId='';$IpAddress='203.0.113.99' $denied=$false try { Invoke-Expression $prefix } catch { $denied=$_.Exception.Message -eq 'discovery_observation_required' } if (!$denied -or $script:targetRequests -ne 0) { throw 'Missing identity was not rejected before I/O' } $checks++ $DiscoveryId='00000000-0000-4000-8000-000000000001';$ObservationVersion='version';$CommandId='command' Invoke-Expression $prefix if ($IpAddress -ne '198.51.100.10' -or $script:targetRequests -ne 1) { throw 'Unvalidated target retained' } $checks++ Write-Output "Discovery PowerShell checks passed: $checks; mocked Hub only; zero miner sockets."