Payload/scripts/kaden/utils/repair-inherited-recorder-source.ps1
|
<# .SYNOPSIS Append script-runner corrections for harness-script rows stamped parent-inherited. .DESCRIPTION Finds PhaseStatusChanged, SensorRunRecorded, and GateCheckRun rows whose recorder tool is harness-script and whose model_source is parent-inherited. Those rows are the role mis-stamp: the parent copied ModelRole subagent onto harness-record-phase. The original lines stay in the journal. This script appends a new row with refs.amends_event_id set to the original event id and model_source script-runner. The inherited-source gate reads that chain tip. An ActivityAdjusted row does not. Rows whose linked artifact already attests a child are left alone. A real cursor-task or copilot-agent delegation is left alone. A feature-phase correction does not move current_phase. Nothing is written unless -Apply is present. .PARAMETER Feature Feature slug under docs/harness/features. Default: host-surface-consistency. .PARAMETER RepoRoot Repository root. Default: walk up from this script to scripts/kaden/harness-invoke.ps1. .PARAMETER FeatureRoot Existing feature folder. Default: docs/harness/features/<Feature>. .PARAMETER AllowArbitraryFeatureRoot Allow -FeatureRoot outside docs/harness/features. For a fixture. .PARAMETER Apply Append the correction rows and rebuild .review-loop.json. .EXAMPLE pwsh -NoProfile -File .\scripts\kaden\utils\repair-inherited-recorder-source.ps1 .EXAMPLE pwsh -NoProfile -File .\scripts\kaden\utils\repair-inherited-recorder-source.ps1 -Feature host-surface-consistency -Apply .EXAMPLE Get-Help .\scripts\kaden\utils\repair-inherited-recorder-source.ps1 -Parameter Apply #> #Requires -Version 5.1 [CmdletBinding(DefaultParameterSetName = 'Repair')] param( [Parameter(ParameterSetName = 'Repair')] [ValidateNotNullOrEmpty()] [ValidatePattern('^[A-Za-z0-9][A-Za-z0-9_-]*$')] [string]$Feature = 'host-surface-consistency', [Parameter(ParameterSetName = 'Repair')] [string]$RepoRoot = '', [Parameter(ParameterSetName = 'Repair')] [string]$FeatureRoot = '', [Parameter(ParameterSetName = 'Repair')] [switch]$AllowArbitraryFeatureRoot, [Parameter(ParameterSetName = 'Repair')] [switch]$Apply, [Parameter(ParameterSetName = 'Help')] [Alias('h', 'help')] [switch]$ShowHelp ) Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' $cliKitManifest = Join-Path $PSScriptRoot 'PsCliUiKit\PsCliUiKit.psd1' if (-not (Test-Path -LiteralPath $cliKitManifest)) { throw "PsCliUiKit manifest not found: $cliKitManifest" } Import-Module -Name $cliKitManifest -Force function Resolve-RepairInheritedRepoRoot { param([string]$RequestedRoot) if (-not [string]::IsNullOrWhiteSpace($RequestedRoot)) { $resolved = (Resolve-Path -LiteralPath $RequestedRoot).Path $marker = Join-Path $resolved 'scripts\kaden\harness-invoke.ps1' if (-not (Test-Path -LiteralPath $marker)) { throw "RepoRoot is not a Kaden checkout (missing scripts\kaden\harness-invoke.ps1): $resolved" } return $resolved } $current = $PSScriptRoot while ($true) { $marker = Join-Path $current 'scripts\kaden\harness-invoke.ps1' if (Test-Path -LiteralPath $marker) { return $current } $parent = Split-Path $current -Parent if ([string]::IsNullOrWhiteSpace($parent) -or $parent -eq $current) { throw 'Could not locate repository root (scripts\kaden\harness-invoke.ps1) from this script.' } $current = $parent } } function Copy-RepairInheritedPayload { param($Payload) $copy = [ordered]@{} if ($null -ne $Payload) { foreach ($property in @($Payload.PSObject.Properties)) { $copy[$property.Name] = $property.Value } } $copy['model_source'] = 'script-runner' return [pscustomobject]$copy } try { if ($ShowHelp) { (Get-Help -Name $PSCommandPath -Full | Out-String -Width 100) | Out-Host return } Write-CliSection -Title 'Repair inherited recorder source' -Style info $root = Resolve-RepairInheritedRepoRoot -RequestedRoot $RepoRoot Import-Module (Join-Path $root 'scripts\kaden\harness\lib\HarnessContract.psm1') -Force Import-Module (Join-Path $root 'scripts\kaden\harness\lib\HarnessJournal.psm1') -Force Import-Module (Join-Path $root 'scripts\kaden\harness\lib\HarnessGateProjection.psm1') -Force $featureRootPath = Get-HarnessFeatureRoot -RepoRoot $root -Feature $Feature -FeatureRootOverride $FeatureRoot -AllowArbitraryFeatureRoot:$AllowArbitraryFeatureRoot $journalPath = Join-Path $featureRootPath 'journal\events.jsonl' if (-not (Test-Path -LiteralPath $journalPath)) { throw "Journal not found: $journalPath" } $watchedKinds = @('PhaseStatusChanged', 'SensorRunRecorded', 'GateCheckRun') $watched = @( Get-HarnessJournalEvents -FeatureRoot $featureRootPath | Where-Object { $watchedKinds -contains [string]$_.kind } ) $tips = @(Select-HarnessGreenAmendmentChainTip -Events $watched) $targets = [System.Collections.Generic.List[object]]::new() foreach ($evt in $tips) { $source = (Get-HarnessEventModelSource -JournalEvent $evt).ToLowerInvariant() if ($source -ne 'parent-inherited') { continue } if ((Get-HarnessEventActorTool -JournalEvent $evt) -ne 'harness-script') { continue } $linked = Get-HarnessPhaseSensorLinkedArtifactRel -JournalEvent $evt if (Test-HarnessLinkedArtifactAttestsChildModel -FeatureRoot $featureRootPath -LinkedArtifact $linked) { continue } $targets.Add($evt) } Write-CliKeyValue -Label 'feature' -Value $Feature Write-CliKeyValue -Label 'rows' -Value ([string]$targets.Count) foreach ($evt in $targets) { $seq = [string](Get-HarnessProperty -Object $evt -Name 'seq' -Default '') $slice = [string](Get-HarnessProperty -Object $evt -Name 'slice' -Default '') $eventId = [string](Get-HarnessProperty -Object $evt -Name 'event_id' -Default '') Write-CliKeyValue -Label "seq $seq" -Value "$slice $eventId" } if ($targets.Count -eq 0) { Write-CliStatus -State 'Info' -Message 'No harness-script parent-inherited rows need a correction.' return } if (-not $Apply) { Write-CliStatus -State 'Info' -Message 'Nothing was written. Pass -Apply to append the script-runner corrections.' return } $written = [System.Collections.Generic.List[string]]::new() foreach ($evt in $targets) { $eventId = [string](Get-HarnessProperty -Object $evt -Name 'event_id' -Default '') $slice = [string](Get-HarnessProperty -Object $evt -Name 'slice' -Default '') $payload = Get-HarnessProperty -Object $evt -Name 'payload' -Default $null $activity = Get-HarnessProperty -Object $evt -Name 'activity' -Default $null $actor = Get-HarnessProperty -Object $evt -Name 'actor' -Default $null $model = Get-HarnessProperty -Object $actor -Name 'model' -Default $null $provider = [string](Get-HarnessProperty -Object $model -Name 'provider' -Default 'other') $slug = [string](Get-HarnessProperty -Object $model -Name 'slug' -Default 'unknown') $agent = [string](Get-HarnessProperty -Object $actor -Name 'agent' -Default 'operator') $activityType = [string](Get-HarnessProperty -Object $activity -Name 'type' -Default 'pipeline.phase') $activityName = [string](Get-HarnessProperty -Object $activity -Name 'name' -Default 'quality-gates') $refsIn = Get-HarnessProperty -Object $evt -Name 'refs' -Default $null $artifact = [string](Get-HarnessProperty -Object $refsIn -Name 'artifact' -Default '') $turnId = Get-HarnessProperty -Object $refsIn -Name 'turn_id' -Default $null $fixActor = New-HarnessJournalActor -Agent $agent -ParentAgent $null -Tool 'harness-script' ` -Provider $provider -Slug $slug -Role 'primary' -ModelSource 'script-runner' $fixActivity = New-HarnessJournalActivity -Id (New-HarnessJournalActivityId) -Type $activityType -Name $activityName -Role 'instant' $fixRefs = [pscustomobject]@{ amends_event_id = $eventId pair_event_id = $null artifact = $(if ([string]::IsNullOrWhiteSpace($artifact)) { $null } else { $artifact }) command = '.\scripts\kaden\utils\repair-inherited-recorder-source.ps1' turn_id = $turnId } $added = Add-HarnessJournalEvent -FeatureRoot $featureRootPath -Feature $Feature -Slice $slice ` -Kind ([string]$evt.kind) -Activity $fixActivity -Actor $fixActor -Outcome $null ` -Summary "Recorder source correction amends $eventId. Honest source is script-runner." ` -Payload (Copy-RepairInheritedPayload -Payload $payload) -Refs $fixRefs $written.Add([string]$added.event_id) } Update-HarnessGateProjectionFromJournal -FeatureRoot $featureRootPath -Feature $Feature -RepoRoot $root -Write | Out-Null Write-CliSection -Title 'Recorder source corrected' -Style success foreach ($id in $written) { Write-CliKeyValue -Label 'event' -Value $id } } catch { Write-CliSection -Title 'Recorder source repair failed' -Style 'error' Write-CliStatus -State 'Error' -Message $_.Exception.Message exit 2 } finally { Write-CliEnd } |