Private/Resolve-KadenIntegrationPairState.ps1

function Resolve-KadenIntegrationPairState {
    <#
    .SYNOPSIS
        Classify one old/new managed rename pair and perform a proven old-only move when required.
    .DESCRIPTION
        Returns Outcome, optional Result row, Whether the new destination must be skipped
        from managed apply, and whether the pair produced a remaining collision.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)][string]$ChildRoot,
        [Parameter(Mandatory = $true)][string]$OldRel,
        [Parameter(Mandatory = $true)][string]$NewRel,
        [Parameter(Mandatory = $false)][string]$ExpectedDigest
    )

    $oldPath = Resolve-KadenContainedPath -Root $ChildRoot -RelativePath $OldRel
    $newPath = Resolve-KadenContainedPath -Root $ChildRoot -RelativePath $NewRel
    $oldExists = Test-Path -LiteralPath $oldPath
    $newExists = Test-Path -LiteralPath $newPath

    $newManaged = $false
    if ($newExists -and -not [string]::IsNullOrWhiteSpace($ExpectedDigest)) {
        $newManaged = ((Get-KadenFileDigest -LiteralPath $newPath) -eq $ExpectedDigest)
    }

    $protectNew = ($newExists -and -not $newManaged)
    if (-not $oldExists -and -not $newExists) {
        return [pscustomobject]@{
            Result     = $null
            ProtectNew = $protectNew
        }
    }

    if (-not $oldExists -and $newExists) {
        return [pscustomobject]@{
            Result     = (New-KadenMigrationResult -OldPath $OldRel -NewPath $NewRel `
                    -Outcome 'already-migrated' -NextAction 'No migration remains for this artifact.')
            ProtectNew = $protectNew
        }
    }

    if ($oldExists -and $newExists) {
        return [pscustomobject]@{
            Result     = (New-KadenMigrationResult -OldPath $OldRel -NewPath $NewRel `
                    -Outcome 'collision' `
                    -NextAction 'Non-destructive review: keep both paths unchanged until ownership is proven; do not overwrite either file.')
            ProtectNew = $true
        }
    }

    # old exists, new absent
    $oldManaged = $false
    if (-not [string]::IsNullOrWhiteSpace($ExpectedDigest)) {
        $oldManaged = ((Get-KadenFileDigest -LiteralPath $oldPath) -eq $ExpectedDigest)
    }
    if (-not $oldManaged) {
        return [pscustomobject]@{
            Result     = (New-KadenMigrationResult -OldPath $OldRel -NewPath $NewRel `
                    -Outcome 'collision' `
                    -NextAction 'Non-destructive review: old path is not proven Kaden-managed; leave it and create or inspect the Kaden-named destination manually.')
            ProtectNew = $false
        }
    }

    $newDir = Split-Path -Parent $newPath
    if (-not (Test-Path -LiteralPath $newDir)) {
        New-Item -ItemType Directory -Path $newDir -Force | Out-Null
    }
    Move-Item -LiteralPath $oldPath -Destination $newPath
    return [pscustomobject]@{
        Result     = (New-KadenMigrationResult -OldPath $OldRel -NewPath $NewRel `
                -Outcome 'migrated' -NextAction 'Artifact moved to the Kaden-named destination.')
        ProtectNew = $false
    }
}