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 six-word beta
        invitation. 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 = [System.IO.Path]::GetFullPath($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 = 'This general-availability release does not request beta acknowledgement. This release remains publicly available. An earlier installed public release remains available and was not revoked. It was not disabled.'
    }
    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 = [string](Get-Module -Name Kaden -ErrorAction SilentlyContinue).Version
    if ([string]::IsNullOrWhiteSpace($moduleVersion)) {
        $manifest = Import-PowerShellDataFile -Path (Join-Path $script:KadenModuleRoot 'Kaden.psd1')
        $moduleVersion = [string]$manifest.ModuleVersion
    }

    $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
        OverlayGuidance = 'Child-owned overlays outside the managed-file manifest are preserved. Intentional overlay replacement is deferred until a later slice exposes -Force.'
    }
}