Payload/scripts/kaden/advisory/AdvisoryOperatorSurface.ps1

# Dot-sourced into AdvisoryWorkflow.psm1 - operator-surface maps and readable report.

$script:AdvisoryCrossEntrySentence = 'advisory context may inform, journal, diagnose, or route work; only canonical gate artifacts select the mandatory next action; failed or unreadable advisory evidence is recovered or omitted and does not block that action.'

$script:AdvisoryActionClassMap = [ordered]@{
    'issue'                 = 'workflow'
    'decision'              = 'workflow'
    'amendment'             = 'workflow'
    'route'                 = 'workflow'
    'rebuild-index'         = 'maintenance'
    'resume-context'        = 'evidence'
    'projection-exclusion'  = 'evidence'
    'verify-integration'    = 'evidence'
}

$script:AdvisoryDefaultOwnerByRoute = @{
    specification   = 'spec-writer'
    'domain-design' = 'ddd-architect'
    implementation  = 'atdd-developer'
}

function Get-AdvisoryCrossEntrySentence {
    return $script:AdvisoryCrossEntrySentence
}

function Get-AdvisoryActionClass {
    param([Parameter(Mandatory = $true)][string]$Action)
    $class = $script:AdvisoryActionClassMap[$Action]
    if ([string]::IsNullOrWhiteSpace([string]$class)) { return 'unknown' }
    return [string]$class
}

function Get-AdvisoryDefaultOwnerForRoute {
    param([AllowNull()][string]$RouteTo)
    if ([string]::IsNullOrWhiteSpace($RouteTo)) { return $null }
    if ($script:AdvisoryDefaultOwnerByRoute.ContainsKey($RouteTo)) {
        return [string]$script:AdvisoryDefaultOwnerByRoute[$RouteTo]
    }
    return $null
}

function ConvertTo-AdvisoryMarkdownCell {
    param([AllowNull()]$Value)
    $text = [string]$Value
    if ([string]::IsNullOrEmpty($text)) { return '' }
    $text = $text.Replace('|', '\|')
    $text = $text.Replace("`r`n", ' ').Replace("`n", ' ').Replace("`r", ' ')
    # Prevent fence shadowing of the trailing advisory-record block.
    $text = $text -replace '```+', "'''"
    return $text
}

function ConvertTo-AdvisoryFindingMarkdownRow {
    param(
        $Finding,
        [string]$DecisionName
    )
    return ('| {0} | {1} | {2} | {3} | {4} | {5} | {6} | {7} | {8} |' -f `
        (ConvertTo-AdvisoryMarkdownCell (Get-AdvisoryWorkflowProperty -Record $Finding -Name 'finding_id')), `
        (ConvertTo-AdvisoryMarkdownCell (Get-AdvisoryWorkflowProperty -Record $Finding -Name 'impact')), `
        (ConvertTo-AdvisoryMarkdownCell (Get-AdvisoryWorkflowProperty -Record $Finding -Name 'evidence')), `
        (ConvertTo-AdvisoryMarkdownCell (Get-AdvisoryWorkflowProperty -Record $Finding -Name 'consequence')), `
        (ConvertTo-AdvisoryMarkdownCell (Get-AdvisoryWorkflowProperty -Record $Finding -Name 'consequence_class')), `
        (ConvertTo-AdvisoryMarkdownCell (Get-AdvisoryWorkflowProperty -Record $Finding -Name 'confidence')), `
        (ConvertTo-AdvisoryMarkdownCell (Get-AdvisoryWorkflowProperty -Record $Finding -Name 'route_to')), `
        (ConvertTo-AdvisoryMarkdownCell (Get-AdvisoryWorkflowProperty -Record $Finding -Name 'recommendation')), `
        (ConvertTo-AdvisoryMarkdownCell $DecisionName))
}

function ConvertTo-AdvisoryDecisionMarkdownRow {
    param($Decision)
    return ('| {0} | {1} | {2} | {3} | {4} | {5} | {6} | {7} | {8} | {9} |' -f `
        (ConvertTo-AdvisoryMarkdownCell (Get-AdvisoryWorkflowProperty -Record $Decision -Name 'finding_id')), `
        (ConvertTo-AdvisoryMarkdownCell (Get-AdvisoryWorkflowProperty -Record $Decision -Name 'decision')), `
        (ConvertTo-AdvisoryMarkdownCell (Get-AdvisoryWorkflowProperty -Record $Decision -Name 'decided_by')), `
        (ConvertTo-AdvisoryMarkdownCell (Get-AdvisoryWorkflowProperty -Record $Decision -Name 'decided_at')), `
        (ConvertTo-AdvisoryMarkdownCell (Get-AdvisoryWorkflowProperty -Record $Decision -Name 'rationale')), `
        (ConvertTo-AdvisoryMarkdownCell (Get-AdvisoryWorkflowProperty -Record $Decision -Name 'selected_work_destination')), `
        (ConvertTo-AdvisoryMarkdownCell (Get-AdvisoryWorkflowProperty -Record $Decision -Name 'next_owner')), `
        (ConvertTo-AdvisoryMarkdownCell (Get-AdvisoryWorkflowProperty -Record $Decision -Name 'trigger_or_needed_information')), `
        (ConvertTo-AdvisoryMarkdownCell (Get-AdvisoryWorkflowProperty -Record $Decision -Name 'destination_reference')), `
        (ConvertTo-AdvisoryMarkdownCell (Get-AdvisoryWorkflowProperty -Record $Decision -Name 'status')))
}

function ConvertTo-AdvisoryReadableReportMarkdown {
    param($Assessment)
    $statement = [string](Get-AdvisoryWorkflowProperty -Record $Assessment -Name 'non_gating_statement')
    $findings = @((Get-AdvisoryWorkflowProperty -Record $Assessment -Name 'findings'))
    $decisions = @((Get-AdvisoryWorkflowProperty -Record $Assessment -Name 'decisions'))
    $decisionById = @{}
    foreach ($decision in $decisions) {
        $decisionById[[string](Get-AdvisoryWorkflowProperty -Record $decision -Name 'finding_id')] = $decision
    }
    $findingRows = @()
    foreach ($finding in $findings) {
        $id = [string](Get-AdvisoryWorkflowProperty -Record $finding -Name 'finding_id')
        $decisionName = ''
        if ($decisionById.ContainsKey($id)) {
            $decisionName = [string](Get-AdvisoryWorkflowProperty -Record $decisionById[$id] -Name 'decision')
        }
        $findingRows += (ConvertTo-AdvisoryFindingMarkdownRow -Finding $finding -DecisionName $decisionName)
    }
    $decisionRows = @()
    foreach ($decision in $decisions) {
        $decisionRows += (ConvertTo-AdvisoryDecisionMarkdownRow -Decision $decision)
    }
    $json = ConvertTo-AdvisoryWorkflowCanonicalJson -Value $Assessment
    $lines = @(
        '# Second-Opinion Advisory Report'
        ''
        '## Advisory identity'
        ''
        '| Field | Value |'
        '| --- | --- |'
        ('| report_id | {0} |' -f (ConvertTo-AdvisoryMarkdownCell (Get-AdvisoryWorkflowProperty -Record $Assessment -Name 'report_id')))
        ('| issued_at | {0} |' -f (ConvertTo-AdvisoryMarkdownCell (Get-AdvisoryWorkflowProperty -Record $Assessment -Name 'issued_at')))
        ('| feature | {0} |' -f (ConvertTo-AdvisoryMarkdownCell (Get-AdvisoryWorkflowProperty -Record $Assessment -Name 'feature')))
        ('| target | {0} |' -f (ConvertTo-AdvisoryMarkdownCell (Get-AdvisoryWorkflowProperty -Record $Assessment -Name 'target')))
        ('| target_reference | {0} |' -f (ConvertTo-AdvisoryMarkdownCell (Get-AdvisoryWorkflowProperty -Record $Assessment -Name 'target_reference')))
        ('| review_question | {0} |' -f (ConvertTo-AdvisoryMarkdownCell (Get-AdvisoryWorkflowProperty -Record $Assessment -Name 'review_question')))
        ('| evidence_boundary | {0} |' -f (ConvertTo-AdvisoryMarkdownCell (Get-AdvisoryWorkflowProperty -Record $Assessment -Name 'evidence_boundary')))
        ('| intentional_latitude | {0} |' -f (ConvertTo-AdvisoryMarkdownCell (Get-AdvisoryWorkflowProperty -Record $Assessment -Name 'intentional_latitude')))
        ('| reviewer_provenance | {0} |' -f (ConvertTo-AdvisoryMarkdownCell (Get-AdvisoryWorkflowProperty -Record $Assessment -Name 'reviewer_provenance')))
        ''
        '## Advisory boundary'
        ''
        (ConvertTo-AdvisoryMarkdownCell $statement)
        ''
        '## Ranked findings'
        ''
        '| finding_id | impact | evidence | consequence | consequence_class | confidence | route_to | recommendation or options | Decision |'
        '| --- | --- | --- | --- | --- | --- | --- | --- | --- |'
    )
    $lines += $findingRows
    $lines += @(
        ''
        '## Decision register'
        ''
        '| finding_id | decision | decided_by | decided_at | rationale | selected_work_destination | next_owner | trigger_or_needed_information | destination_reference | status |'
        '| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |'
    )
    $lines += $decisionRows
    $lines += @(
        ''
        '```advisory-record'
        $json
        '```'
        ''
    )
    return ($lines -join "`n")
}