private/ActionHelpers.ps1
|
# Shared Action constructor (data-model.md -> Action) so every category file builds the same # shape instead of repeating a pscustomobject literal eight times. function New-OctaAction { [CmdletBinding()] param( [Parameter(Mandatory)][ValidateSet('Registry', 'Service', 'ScheduledTask', 'Package')] [string]$TargetType, [Parameter(Mandatory)][string]$TargetIdentifier, $CurrentValue, $PlannedValue, [bool]$Reversible = $true, [string]$IrreversibleReason = $null, [bool]$HeuristicMatch = $false, [ValidateSet('Safe', 'Moderate', 'Risky')] [string]$RiskLevel = 'Safe' ) if (-not $Reversible -and -not $IrreversibleReason) { throw "New-OctaAction: IrreversibleReason is required when Reversible = `$false (FR-007) for target '$TargetIdentifier'." } return [pscustomobject]@{ TargetType = $TargetType TargetIdentifier = $TargetIdentifier CurrentValue = $CurrentValue PlannedValue = $PlannedValue Reversible = $Reversible IrreversibleReason = $IrreversibleReason HeuristicMatch = $HeuristicMatch RiskLevel = $RiskLevel } } function Split-OctaActionsByConfirmationGroup { <# .SYNOPSIS Partitions {Category,Action} entries into the three independent confirmation gates Invoke-OctaCategory uses: Normal (Safe/Moderate, non-heuristic), Heuristic (HeuristicMatch, e.g. oem-suites), and Risky (RiskLevel -eq 'Risky'). Risky takes precedence when an action happens to be both, so it only needs one gate, not two - FR-017, FR-026. #> [CmdletBinding()] param( [AllowEmptyCollection()][object[]]$Entries = @() ) $risky = @($Entries | Where-Object { $_.Action.RiskLevel -eq 'Risky' }) $heuristic = @($Entries | Where-Object { $_.Action.HeuristicMatch -and $_.Action.RiskLevel -ne 'Risky' }) $normal = @($Entries | Where-Object { -not $_.Action.HeuristicMatch -and $_.Action.RiskLevel -ne 'Risky' }) return [pscustomobject]@{ Normal = $normal; Heuristic = $heuristic; Risky = $risky } } |