Modules/businessdev.ALbuild.Core/Private/Get-ALbuildDockerPruneArgument.ps1

function Get-ALbuildDockerPruneArgument {
    <#
    .SYNOPSIS
        Builds the 'docker image prune' argument list, excluding protected image labels.
 
    .DESCRIPTION
        Kept separate from Clear-ALbuildCache for one reason: this is the argument list that decides
        whether the BC image cache survives a prune, and it must be verifiable without a Docker engine
        (the module's CI leg runs on Linux, where 'docker' is not resolvable and cannot be mocked).
        As a pure function it is asserted directly in the unit tests.
 
        'prune -a' removes every unused image, so each protected label is added as a negated filter.
        Docker AND-combines filter keys and honours 'label!=' (verified against engine 28.5.1).
 
    .PARAMETER KeepDays
        Retention window in days; converted to Docker's 'until=<n>h' form.
 
    .PARAMETER ProtectLabel
        Image labels that must never be pruned. Blank entries are ignored.
 
    .OUTPUTS
        System.String[]: the arguments to pass to the docker executable.
    #>

    [CmdletBinding()]
    [OutputType([string[]])]
    param(
        [Parameter(Mandatory)] [ValidateRange(0, [int]::MaxValue)] [int] $KeepDays,
        [string[]] $ProtectLabel = @()
    )

    # Not $args - that is an automatic variable; shadowing it is a trap under Set-StrictMode.
    $pruneArgs = @('image', 'prune', '-a', '-f', '--filter', "until=$([int]($KeepDays * 24))h")
    foreach ($label in @($ProtectLabel | Where-Object { -not [string]::IsNullOrWhiteSpace($_) })) {
        $pruneArgs += @('--filter', "label!=$label")
    }
    return , [string[]]$pruneArgs
}