Payload/scripts/harness/harness-own-slice.ps1
|
#Requires -Version 5.1 <# .SYNOPSIS Own-slice status with optional -Bootstrap / -ExecuteNext for harness-safe hops. .DESCRIPTION Runs the own-slice checklist (same as harness-own-slice-status.ps1). -Bootstrap: if no open turn for the slice, runs harness-turn-start for the first incomplete ATDD phase, then prints checklist + NEXT and writes sensors/own-slice-next.json. Canonical first hop after "@atdd-developer own ...". -ExecuteNext: runs the first harness-safe segment of the printed next command via harness-invoke. Does not dispatch AI reviewers or forge artifacts. .EXAMPLE pwsh -File scripts/harness-invoke.ps1 harness-own-slice.ps1 -Feature saved-search-queries -Slice mo-save-list -Bootstrap -ModelProvider cursor -ModelSlug composer-2.5 .EXAMPLE pwsh -File scripts/harness-invoke.ps1 harness-own-slice.ps1 -Feature saved-search-queries -Slice mo-save-list -ExecuteNext -ModelProvider cursor -ModelSlug composer-2.5 #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$Feature, [Parameter(Mandatory = $true)] [string]$Slice, [string]$FeatureRoot = '', [string]$RepoRoot = '', [switch]$AllowArbitraryFeatureRoot, [switch]$Bootstrap, [switch]$ExecuteNext, [ValidateSet('RED', 'GREEN', 'MUTATE', 'REFACTOR', 'COMMIT', '')] [string]$Phase = '', [string]$ModelProvider = '', [string]$ModelSlug = '', [switch]$Json ) Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' Import-Module (Join-Path $PSScriptRoot 'lib\HarnessContract.psm1') -Force Import-Module (Join-Path $PSScriptRoot 'lib\HarnessJournal.psm1') -Force Test-HarnessContractModuleReady if ([string]::IsNullOrWhiteSpace($RepoRoot)) { $RepoRoot = Get-HarnessRepoRoot -StartPath $PSScriptRoot } $featureRootPath = Get-HarnessFeatureRoot -RepoRoot $RepoRoot -Feature $Feature ` -FeatureRootOverride $FeatureRoot -AllowArbitraryFeatureRoot:$AllowArbitraryFeatureRoot $exitCode = 0 if ($Bootstrap -and $ExecuteNext) { throw 'harness-own-slice: -Bootstrap and -ExecuteNext are mutually exclusive.' } if ($Bootstrap) { $turnOpen = Test-HarnessSliceTurnOpen -FeatureRoot $featureRootPath -Slice $Slice if (-not $turnOpen) { if ([string]::IsNullOrWhiteSpace($ModelProvider) -or [string]::IsNullOrWhiteSpace($ModelSlug)) { throw 'harness-own-slice -Bootstrap: pass -ModelProvider and -ModelSlug when starting a turn.' } $loop = Get-ReviewLoopDocument -FeatureRoot $featureRootPath $sliceEntry = Get-ImplementationSliceEntry -LoopData $loop.Data -SliceId $Slice if (-not $sliceEntry) { throw "Slice '$Slice' not found. Run init / repair review-loop before owning." } $bootPhase = Get-HarnessOwnSliceBootstrapPhase -SliceEntry $sliceEntry -PhaseOverride $Phase $turnStart = Join-Path $PSScriptRoot 'harness-turn-start.ps1' Write-Output "[harness-own-slice] Bootstrap: starting turn (phase $bootPhase)" & $turnStart -Feature $Feature -Slice $Slice -Phase $bootPhase ` -ModelProvider $ModelProvider -ModelSlug $ModelSlug if ($LASTEXITCODE -ne 0 -and $null -ne $LASTEXITCODE) { throw "harness-own-slice -Bootstrap: turn-start exited $LASTEXITCODE" } } else { Write-Output '[harness-own-slice] Bootstrap: turn already open -- checklist only' } } if ($ExecuteNext) { $before = Get-HarnessOwnSliceReport -FeatureRoot $featureRootPath -Feature $Feature -Slice $Slice -RepoRoot $RepoRoot $next = $before.next_step if (-not $next) { throw 'No next step with a command; own-slice checklist is complete or blocked without a harness hop.' } if ($next.status -eq 'blocked') { throw "Next step '$($next.id)' is blocked ($($next.detail)); -ExecuteNext cannot remediate reviewer cycles." } $segment = Get-HarnessOwnSliceFirstInvokeSegment -NextCommand $next.next if ([string]::IsNullOrWhiteSpace($segment)) { throw "Next step '$($next.id)' has no harness-invoke segment for -ExecuteNext: $($next.next)" } Write-Output "[harness-own-slice] ExecuteNext: $($next.id)" Write-Output " $segment" $hopCode = Invoke-HarnessOwnSliceNextHop -RepoRoot $RepoRoot -InvokeSegment $segment ` -ModelProvider $ModelProvider -ModelSlug $ModelSlug Write-Output "[harness-own-slice] hop exit code: $hopCode" if ($hopCode -ne 0) { $exitCode = $hopCode } } $result = Get-HarnessOwnSliceReport -FeatureRoot $featureRootPath -Feature $Feature -Slice $Slice -RepoRoot $RepoRoot $todoCount = $result.remaining_count $artifactPath = Write-HarnessOwnSliceNextArtifact -FeatureRoot $featureRootPath -Report $result if (-not $Json) { $header = if ($Bootstrap) { 'Own-slice bootstrap' } else { 'Own-slice runner' } Format-HarnessOwnSliceHumanReport -Report $result -Header $header | ForEach-Object { Write-Output $_ } Write-Output " Wrote: $artifactPath" Write-Output '' } $result | ConvertTo-Json -Depth 6 if ($todoCount -gt 0 -and $exitCode -eq 0) { exit 2 } exit $exitCode |