Public/Initialize-KadenRepo.ps1

function Initialize-KadenRepo {
    <#
    .SYNOPSIS
        Initialize a child repository from the installed Kaden payload.
    .DESCRIPTION
        When this installed release channel is beta, validates the PascalCase beta
        invitation passphrase. When the installed release channel is ga, beta acknowledgement
        is not requested. Then checks the embedded payload, applies allowlisted
        managed files, and writes `.kaden.json` / `.kaden.local.json`.
        When shared configuration is absent and `.sync-project-id` holds a valid
        project identity, that identity is recorded and the legacy file is left unchanged.
        A later general-availability install does not change an earlier installed copy.
    .EXAMPLE
        $invite = New-KadenBetaInvitation
        Initialize-KadenRepo -Path . -ProjectId 'mac-test-suite' -BetaInvitation $invite
    .EXAMPLE
        # A later release whose packaged channel is ga. This 0.1.0 module is beta.
        Initialize-KadenRepo -Path . -ProjectId 'mac-test-suite'
    #>

    [CmdletBinding(SupportsShouldProcess = $true)]
    param(
        [Parameter(Mandatory = $true)]
        [string]$Path,

        [Parameter(Mandatory = $true)]
        [string]$ProjectId,

        [Parameter(Mandatory = $false)]
        [AllowEmptyString()]
        [string]$BetaInvitation
    )

    $childRoot = Resolve-KadenChildRoot -Path $Path
    if (-not (Test-Path -LiteralPath $childRoot)) {
        throw "KDN-TXN-PREFLIGHT-FAILED: Child repository path does not exist: $childRoot"
    }

    if (-not $PSCmdlet.ShouldProcess($childRoot, 'Initialize-KadenRepo')) {
        return
    }

    $channel = Get-KadenReleaseChannel
    if ($channel -eq 'ga') {
        $guidance = 'General-availability release: no beta invitation needed. Earlier installed copies stay on the machine unchanged.'
    }
    else {
        $invitation = Test-KadenBetaInvitation -Invitation ([string]$BetaInvitation)
        if (-not $invitation.Valid) {
            throw $invitation.Message
        }
        $guidance = $invitation.Message
    }

    $payload = Test-KadenPackagePayload
    if (-not $payload.Valid) {
        throw $payload.Message
    }

    $moduleVersion = Get-KadenRunningModuleVersion

    $effectiveProjectId = $ProjectId
    $sharedPath = Join-Path $childRoot '.kaden.json'
    if (-not (Test-Path -LiteralPath $sharedPath)) {
        $legacyProjectId = Get-KadenLegacyProjectId -ChildRoot $childRoot
        if (-not [string]::IsNullOrWhiteSpace($legacyProjectId)) {
            $effectiveProjectId = $legacyProjectId
        }
    }

    Invoke-KadenManagedInitialize -ChildRoot $childRoot -ProjectId $effectiveProjectId `
        -Manifest $payload.Manifest -PayloadRoot (Get-KadenPayloadRoot) -ModuleVersion $moduleVersion

    return [pscustomobject]@{
        Succeeded      = $true
        Path           = $childRoot
        ProjectId      = $effectiveProjectId
        AppliedVersion = $moduleVersion
        Guidance       = $guidance
    }
}