private/RunRecord.ps1

# data-model.md -> Run Record: %LOCALAPPDATA%\Octa\runs\<yyyyMMdd-HHmmss>\run.json
# research.md -> per-user, no elevation needed to write, self-contained per-run folder.

function Get-OctaRunsRoot {
    $rootPath = Join-Path $env:LOCALAPPDATA 'Octa\runs'
    if (-not (Test-Path $rootPath)) {
        New-Item -ItemType Directory -Path $rootPath -Force | Out-Null
    }
    return $rootPath
}

function New-OctaRunFolder {
    [CmdletBinding()]
    param()
    $runId = Get-Date -Format 'yyyyMMdd-HHmmss'
    $folder = Join-Path (Get-OctaRunsRoot) $runId
    New-Item -ItemType Directory -Path $folder -Force | Out-Null
    return [pscustomobject]@{ RunId = $runId; Path = $folder }
}

function Save-OctaRunRecord {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)][object]$RunRecord,
        [Parameter(Mandatory)][string]$RunFolder
    )
    $destination = Join-Path $RunFolder 'run.json'
    $RunRecord | ConvertTo-Json -Depth 10 | Set-Content -Path $destination -Encoding utf8
}

function Get-OctaRunRecord {
    <#
        Resolves 'latest' to the most recently created run folder; otherwise looks up the
        given RunId directly. Returns $null when not found (bin/octa.ps1 maps this to exit 4).
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)][string]$RunId
    )

    $runsRoot = Get-OctaRunsRoot

    if ($RunId -eq 'latest') {
        $latestFolder = Get-ChildItem -Path $runsRoot -Directory -ErrorAction SilentlyContinue |
            Sort-Object Name -Descending | Select-Object -First 1
        if (-not $latestFolder) { return $null }
        $runFile = Join-Path $latestFolder.FullName 'run.json'
    }
    else {
        $runFile = Join-Path $runsRoot "$RunId\run.json"
    }

    if (-not (Test-Path $runFile)) {
        return $null
    }

    $record = Get-Content -Path $runFile -Raw | ConvertFrom-Json
    Add-Member -InputObject $record -MemberType NoteProperty -Name 'RunFolder' -Value (Split-Path $runFile -Parent) -Force
    return $record
}