public/Undo-OctaRun.ps1

function Undo-OctaRun {
    <#
        .SYNOPSIS
        Reverts a prior Octa run using its recorded prior-state snapshots (FR-008).

        .PARAMETER RunId
        A specific run id (folder name), or 'latest' for the most recent run.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)][string]$RunId
    )

    $strings = Get-OctaStrings
    $record = Get-OctaRunRecord -RunId $RunId
    if (-not $record) {
        return [pscustomobject]@{ Status = 'NotFound'; Message = ($strings.undoNotFound -f $RunId) }
    }

    if ($record.Status -eq 'Undone') {
        return [pscustomobject]@{ Status = 'AlreadyUndone'; Message = 'This run was already undone.' }
    }

    $restored = @()
    $failed = @()
    $irreversible = @($record.IrreversibleActionRefs)
    $snapshots = @($record.ActionSnapshots) | Where-Object { $_ }

    foreach ($snapshot in $snapshots) {
        try {
            Restore-OctaActionSnapshot -Snapshot $snapshot -RunFolder $record.RunFolder
            $restored += $snapshot.ActionRef
            Write-Host ($strings.undoRestored -f $snapshot.ActionRef)
        }
        catch {
            $failed += $snapshot.ActionRef
        }
    }

    $couldNotUndo = @($irreversible) + @($failed)
    foreach ($ref in $couldNotUndo) {
        Write-Host ($strings.undoIrreversible -f $ref)
    }

    # ponytail: only mark the run Undone when every reversible action actually came back. This
    # used to be unconditional, so a run where every single restore threw still got recorded as
    # Undone and returned Status = 'Success' - which then made a second --undo attempt answer
    # 'AlreadyUndone', permanently blocking the retry for a run that was never undone at all.
    # Verified real: a snapshot pointing at a service that no longer exists restores 0 of 1
    # actions and was still reported as a success.
    $allRestored = ($failed.Count -eq 0)
    $recordStatus = if ($allRestored) { 'Undone' } else { 'PartiallyUndone' }
    Add-Member -InputObject $record -MemberType NoteProperty -Name 'Status' -Value $recordStatus -Force
    Save-OctaRunRecord -RunFolder $record.RunFolder -RunRecord $record

    $status = if ($allRestored) {
        'Success'
    }
    elseif ($restored.Count -gt 0) {
        'PartiallyUndone'
    }
    else {
        'Failed'
    }

    return [pscustomobject]@{
        Status       = $status
        Restored     = $restored
        CouldNotUndo = $couldNotUndo
        Failed       = $failed
    }
}