Disable physical control through legacy HTTP/M30 producers, typed admission, queue dispatch and upgraded Windows executors. Restrict diagnostic transports to exact read-only operations, with ordinal PowerShell validation before sockets. Retire unsupported pending/claimed work with atomic, idempotent security audits. Preserve prior delivery evidence and report unknown outcomes after a prior claim, including explicitly repaired pending rows. Include containment, cancellation, concurrency and malformed-payload regressions and the old-Agent cutover runbook. Validation: independent final application-security revalidation PASS. Two unchanged baseline source-assertion failures are documented as exceptions. Production release still requires native Windows validation and verified fencing/stop/drain/upgrade; server cancellation alone cannot revoke a cached command held by an old Agent.
47 lines
2.2 KiB
PowerShell
47 lines
2.2 KiB
PowerShell
param(
|
|
[Parameter(Mandatory=$true)][string]$BaselineRoot,
|
|
[Parameter(Mandatory=$true)][string]$CachedPayloadPath,
|
|
[Parameter(Mandatory=$true)][string]$MinerIp,
|
|
[switch]$ExpectFenced
|
|
)
|
|
$ErrorActionPreference = "Stop"
|
|
if ($env:MINEROPS_STAGE_A_SIMULATION -ne "1") {
|
|
throw "Requires an explicitly isolated Stage A simulation; never use physical targets."
|
|
}
|
|
|
|
# Supply a git-archived 2d89e80 Windows source directory, NOT a running installation.
|
|
# Only AST function definitions execute; no startup, config loading, or task loops.
|
|
$tokens = $null; $errors = $null
|
|
$ast = [System.Management.Automation.Language.Parser]::ParseFile(
|
|
(Join-Path $BaselineRoot "MinerOpsAgentService.ps1"), [ref]$tokens, [ref]$errors)
|
|
if ($errors.Count) { throw "Baseline parser error" }
|
|
foreach ($definition in $ast.FindAll({
|
|
param($node)
|
|
$node -is [System.Management.Automation.Language.FunctionDefinitionAst] -and
|
|
$node.Parent -is [System.Management.Automation.Language.NamedBlockAst]
|
|
}, $true)) {
|
|
Invoke-Expression $definition.Extent.Text
|
|
}
|
|
. (Join-Path $BaselineRoot "MinerOpsControl.ps1")
|
|
function Read-AgentConfig {
|
|
return [pscustomobject]@{
|
|
api3_account = "simulation"; api3_password = "simulation-only"; api3_port = 4433
|
|
}
|
|
}
|
|
function Get-MinerOpsApi3Salt { return @{ salt = "simulation-only"; salt_response = @{} } }
|
|
|
|
$payload = Get-Content -LiteralPath $CachedPayloadPath -Raw | ConvertFrom-Json
|
|
if ($payload.action -ne "suspend") { throw "This simulation expects the audited cached suspend command" }
|
|
# Remap ONLY the target to the address of the dedicated disposable miner container.
|
|
$payload.ip_address = $MinerIp
|
|
$result = Run-MinerControlCommand -Payload $payload
|
|
if ($ExpectFenced) {
|
|
if ($result.command_accepted -ne $false -or $result.failure_code -ne "write_rejected") {
|
|
throw "Old executor unexpectedly reached/accepted a simulated miner through the fence"
|
|
}
|
|
Write-Host "Fenced old cached command failed; independently verify simulator write count stayed zero."
|
|
} else {
|
|
if ($result.command_accepted -ne $true) { throw "Unfenced control simulation did not reproduce old execution" }
|
|
Write-Host "Unfenced old cached command reproduced; simulated miner received service stop."
|
|
}
|