fix(agent99): complete same-run status reconcile
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m46s
CD Pipeline / build-and-deploy (push) Successful in 19m6s
CD Pipeline / post-deploy-checks (push) Successful in 2m4s
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m46s
CD Pipeline / build-and-deploy (push) Successful in 19m6s
CD Pipeline / post-deploy-checks (push) Successful in 2m4s
This commit is contained in:
@@ -13,6 +13,7 @@ $StateDir = Join-Path $AgentRoot "state"
|
||||
$EvidenceDir = Join-Path $AgentRoot "evidence"
|
||||
$DeployRoot = Join-Path $AgentRoot "deploy"
|
||||
$ManifestPath = Join-Path $StateDir "runtime-manifest.json"
|
||||
$LauncherPath = Join-Path $AgentRoot "agent99-run.ps1"
|
||||
$WindowsPowerShell = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
|
||||
$RelayTaskName = "Wooo-Agent99-SRE-Alert-Relay"
|
||||
$RelayTaskPath = "\"
|
||||
@@ -71,6 +72,48 @@ function Get-AgentSha256File {
|
||||
return (Get-FileHash -LiteralPath $Path -Algorithm SHA256).Hash.ToLowerInvariant()
|
||||
}
|
||||
|
||||
function Get-AgentLauncherContract {
|
||||
$requiredMarkers = @(
|
||||
'[switch]$ReconcileOnly',
|
||||
'[string]$ReconcileEvidenceId = ""',
|
||||
'[switch]$ReconcileQueueOnly',
|
||||
'[string]$ReconcileQueueId = ""',
|
||||
'-ReconcileOnly:$ReconcileOnly',
|
||||
'-ReconcileEvidenceId $ReconcileEvidenceId',
|
||||
'-ReconcileQueueOnly:$ReconcileQueueOnly',
|
||||
'-ReconcileQueueId $ReconcileQueueId'
|
||||
)
|
||||
if (-not (Test-Path -LiteralPath $LauncherPath -PathType Leaf)) {
|
||||
return [pscustomobject]@{
|
||||
schemaVersion = "agent99_launcher_contract_v1"
|
||||
ok = $false
|
||||
exists = $false
|
||||
sha256 = "missing"
|
||||
parseErrorCount = -1
|
||||
requiredMarkerCount = $requiredMarkers.Count
|
||||
missingMarkerCount = $requiredMarkers.Count
|
||||
reconcileOnlyForwarded = $false
|
||||
reconcileQueueOnlyForwarded = $false
|
||||
}
|
||||
}
|
||||
$tokens = $null
|
||||
$parseErrors = $null
|
||||
[Management.Automation.Language.Parser]::ParseFile($LauncherPath, [ref]$tokens, [ref]$parseErrors) | Out-Null
|
||||
$content = [IO.File]::ReadAllText($LauncherPath)
|
||||
$missingMarkers = @($requiredMarkers | Where-Object { -not $content.Contains($_) })
|
||||
return [pscustomobject]@{
|
||||
schemaVersion = "agent99_launcher_contract_v1"
|
||||
ok = [bool](@($parseErrors).Count -eq 0 -and $missingMarkers.Count -eq 0)
|
||||
exists = $true
|
||||
sha256 = (Get-AgentSha256File $LauncherPath)
|
||||
parseErrorCount = @($parseErrors).Count
|
||||
requiredMarkerCount = $requiredMarkers.Count
|
||||
missingMarkerCount = $missingMarkers.Count
|
||||
reconcileOnlyForwarded = [bool]($missingMarkers -notcontains '-ReconcileOnly:$ReconcileOnly' -and $missingMarkers -notcontains '-ReconcileEvidenceId $ReconcileEvidenceId')
|
||||
reconcileQueueOnlyForwarded = [bool]($missingMarkers -notcontains '-ReconcileQueueOnly:$ReconcileQueueOnly' -and $missingMarkers -notcontains '-ReconcileQueueId $ReconcileQueueId')
|
||||
}
|
||||
}
|
||||
|
||||
function Get-AgentSafeRuntimeManifest {
|
||||
if (-not (Test-Path -LiteralPath $ManifestPath -PathType Leaf)) {
|
||||
return [pscustomobject]@{
|
||||
@@ -146,6 +189,7 @@ function Get-AgentLiveBundleDigest {
|
||||
foreach ($name in $FixedRuntimeFiles) {
|
||||
$rows += "$name`t$(Get-AgentSha256File (Join-Path $BinDir $name))`n"
|
||||
}
|
||||
$rows += "agent99-run.ps1`t$(Get-AgentSha256File $LauncherPath)`n"
|
||||
return Get-AgentSha256Bytes ([Text.Encoding]::UTF8.GetBytes(($rows -join "")))
|
||||
}
|
||||
|
||||
@@ -555,6 +599,7 @@ function Restore-AgentBundle {
|
||||
param(
|
||||
[string]$BackupPath,
|
||||
[hashtable]$BeforeFilePresence,
|
||||
[bool]$BeforeLauncherPresent,
|
||||
[bool]$BeforeConfigPresent,
|
||||
[bool]$BeforeManifestPresent
|
||||
)
|
||||
@@ -573,6 +618,13 @@ function Restore-AgentBundle {
|
||||
Remove-Item -LiteralPath $livePath -Force
|
||||
}
|
||||
}
|
||||
$backupLauncher = Join-Path $BackupPath "agent99-run.ps1"
|
||||
if ($BeforeLauncherPresent) {
|
||||
if (-not (Test-Path -LiteralPath $backupLauncher -PathType Leaf)) { throw "required_launcher_backup_missing" }
|
||||
Copy-AgentFileWithRetry $backupLauncher $LauncherPath
|
||||
} elseif (Test-Path -LiteralPath $LauncherPath -PathType Leaf) {
|
||||
Remove-Item -LiteralPath $LauncherPath -Force
|
||||
}
|
||||
$backupConfig = Join-Path $BackupPath "agent99.config.json"
|
||||
if ($BeforeConfigPresent) {
|
||||
if (-not (Test-Path -LiteralPath $backupConfig -PathType Leaf)) { throw "required_config_backup_missing" }
|
||||
@@ -832,6 +884,7 @@ try {
|
||||
}
|
||||
|
||||
$live = Get-AgentSafeRuntimeManifest
|
||||
$liveLauncherContract = Get-AgentLauncherContract
|
||||
if (
|
||||
$prior -and
|
||||
[string]$prior.status -eq "deployed_verified" -and
|
||||
@@ -841,10 +894,15 @@ try {
|
||||
[string]$prior.sourceRevision -eq $sourceRevision -and
|
||||
$prior.PSObject.Properties["relayReload"] -and
|
||||
[bool]$prior.relayReload.newGenerationVerified -and
|
||||
$prior.PSObject.Properties["launcherContract"] -and
|
||||
[bool]$prior.launcherContract.ok -and
|
||||
[string]$prior.launcherContract.sha256 -match "^[0-9a-f]{64}$" -and
|
||||
$live.runtimeMatched -and
|
||||
$live.sourceRevision -eq $sourceRevision -and
|
||||
$live.fileCount -eq 14 -and
|
||||
$live.mismatchCount -eq 0
|
||||
$live.mismatchCount -eq 0 -and
|
||||
$liveLauncherContract.ok -and
|
||||
[string]$liveLauncherContract.sha256 -eq [string]$prior.launcherContract.sha256
|
||||
) {
|
||||
$script:ReceiverOperationPhase = "idempotent_replay_post_verifier"
|
||||
$replayPreflight = Invoke-AgentLivePreflight (Join-Path $stagePath "agent99-live-preflight.ps1")
|
||||
@@ -852,6 +910,7 @@ try {
|
||||
$originalOperationBoundaries = $prior.operationBoundaries
|
||||
$prior | Add-Member -NotePropertyName idempotentReplay -NotePropertyValue $true -Force
|
||||
$prior | Add-Member -NotePropertyName runtimeManifest -NotePropertyValue $live -Force
|
||||
$prior | Add-Member -NotePropertyName launcherContract -NotePropertyValue $liveLauncherContract -Force
|
||||
$prior | Add-Member -NotePropertyName livePreflight -NotePropertyValue $replayPreflight -Force
|
||||
$prior | Add-Member -NotePropertyName originalOperationBoundaries -NotePropertyValue $originalOperationBoundaries -Force
|
||||
$prior | Add-Member -NotePropertyName operationBoundaries -NotePropertyValue ([pscustomobject]@{
|
||||
@@ -979,6 +1038,7 @@ try {
|
||||
$beforeManifestDigest = Get-AgentSha256File $ManifestPath
|
||||
$beforeFilePresence = @{}
|
||||
foreach ($name in $FixedRuntimeFiles) { $beforeFilePresence[$name] = Test-Path -LiteralPath (Join-Path $BinDir $name) -PathType Leaf }
|
||||
$beforeLauncherPresent = Test-Path -LiteralPath $LauncherPath -PathType Leaf
|
||||
$beforeConfigPresent = Test-Path -LiteralPath $ConfigPath -PathType Leaf
|
||||
$beforeManifestPresent = Test-Path -LiteralPath $ManifestPath -PathType Leaf
|
||||
$beforeRelayRuntime = Get-AgentRelayRuntime
|
||||
@@ -1034,6 +1094,7 @@ try {
|
||||
$relayReload = $null
|
||||
$runtimeManifest = $null
|
||||
$livePreflight = $null
|
||||
$launcherContract = $null
|
||||
$postVerified = $false
|
||||
$failurePhase = ""
|
||||
$failureType = ""
|
||||
@@ -1046,7 +1107,15 @@ try {
|
||||
if ($deploy.payload -and $deploy.payload.PSObject.Properties["backupDir"]) {
|
||||
$backupPath = [string]$deploy.payload.backupDir
|
||||
}
|
||||
if (-not $deploy.ok -or -not $deploy.payload -or [string]$deploy.payload.status -ne "deployed" -or $deploy.payload.taskRegistration) {
|
||||
if (
|
||||
-not $deploy.ok -or
|
||||
-not $deploy.payload -or
|
||||
[string]$deploy.payload.status -ne "deployed" -or
|
||||
$deploy.payload.taskRegistration -or
|
||||
-not $deploy.payload.PSObject.Properties["launcherContract"] -or
|
||||
-not [bool]$deploy.payload.launcherContract.ok -or
|
||||
[string]$deploy.payload.launcherContract.sha256 -notmatch "^[0-9a-f]{64}$"
|
||||
) {
|
||||
$failurePhase = "deploy"
|
||||
$failureType = "deploy_child_failed_or_invalid"
|
||||
} else {
|
||||
@@ -1060,6 +1129,7 @@ try {
|
||||
} else {
|
||||
$script:ReceiverOperationPhase = "independent_post_verifier"
|
||||
$runtimeManifest = Get-AgentSafeRuntimeManifest
|
||||
$launcherContract = Get-AgentLauncherContract
|
||||
$livePreflight = Invoke-AgentLivePreflight (Join-Path $stagePath "agent99-live-preflight.ps1")
|
||||
$postVerified = [bool](
|
||||
$runtimeManifest.exists -and
|
||||
@@ -1067,6 +1137,8 @@ try {
|
||||
$runtimeManifest.sourceRevision -eq $sourceRevision -and
|
||||
$runtimeManifest.fileCount -eq 14 -and
|
||||
$runtimeManifest.mismatchCount -eq 0 -and
|
||||
$launcherContract.ok -and
|
||||
[string]$launcherContract.sha256 -eq [string]$deploy.payload.launcherContract.sha256 -and
|
||||
$relayReload.oldGenerationsGone -and
|
||||
$relayReload.newGenerationVerified -and
|
||||
$relayReload.after.taskEnabled -and
|
||||
@@ -1108,6 +1180,7 @@ try {
|
||||
deploy = [pscustomobject]@{ ok = $deploy.ok; exitCode = $deploy.exitCode; timedOut = $deploy.timedOut; status = [string]$deploy.payload.status }
|
||||
relayReload = $relayReload
|
||||
runtimeManifest = $runtimeManifest
|
||||
launcherContract = $launcherContract
|
||||
livePreflight = $livePreflight
|
||||
durableReceiptWritten = $true
|
||||
idempotentReplay = $false
|
||||
@@ -1147,7 +1220,7 @@ try {
|
||||
}
|
||||
$script:ReceiverOperationPhase = "runtime_rollback"
|
||||
$script:ReceiverRollbackAttempted = $true
|
||||
$rollback = Restore-AgentBundle $backupPath $beforeFilePresence $beforeConfigPresent $beforeManifestPresent
|
||||
$rollback = Restore-AgentBundle $backupPath $beforeFilePresence $beforeLauncherPresent $beforeConfigPresent $beforeManifestPresent
|
||||
$rollbackForbiddenGenerations = @($beforeRelayRuntime.taskGeneration)
|
||||
if ($relayReload) {
|
||||
$rollbackForbiddenGenerations += @($relayReload.before.taskGeneration)
|
||||
@@ -1227,6 +1300,7 @@ try {
|
||||
attemptReceiptPath = $attemptReceiptPath
|
||||
relayReload = $relayReload
|
||||
failedRuntimeManifest = $runtimeManifest
|
||||
failedLauncherContract = $launcherContract
|
||||
failedLivePreflight = $livePreflight
|
||||
rollback = $rollback
|
||||
rollbackRelayRestart = $rollbackRelayRestart
|
||||
|
||||
Reference in New Issue
Block a user