48 lines
4.1 KiB
PowerShell
48 lines
4.1 KiB
PowerShell
#Requires -Version 7.0
|
|
param([Parameter(Mandatory=$true)][ValidatePattern('^(before|after|(strict-preflight|list|focused|focused-batch[0-9]{2}|all|clippy|build|diagnostic)-(before|after))$')][string]$Stage)
|
|
Set-StrictMode -Version Latest
|
|
$ErrorActionPreference='Stop'
|
|
$taskWorkspace='C:\Users\User\Documents\Git\ARCADIA-Studio\.local\scenario-spacing-ytr83r-20260913'
|
|
$taskPin='5d4a6a47ce1085b818498bb281a41c3bc6a83847'
|
|
function Hash-Input([string]$Path){(Get-FileHash -LiteralPath $Path -Algorithm SHA256).Hash.ToLowerInvariant()}
|
|
$taskOutput=Join-Path $PSScriptRoot ('inputs-complete-'+$Stage+'.json')
|
|
if(Test-Path -LiteralPath $taskOutput){throw 'Preserve existing input evidence; use a new directory for retries.'}
|
|
$pinRecord=Get-Content -Raw -LiteralPath (Join-Path $PSScriptRoot 'expected-inputs.json')|ConvertFrom-Json
|
|
$enumeration=Get-Content -Raw -LiteralPath (Join-Path $PSScriptRoot 'enumeration.json')|ConvertFrom-Json
|
|
$external=Get-Content -Raw -LiteralPath (Join-Path $PSScriptRoot 'external-inputs.json')|ConvertFrom-Json
|
|
if($pinRecord.base -cne $taskPin -or $enumeration.base -cne $taskPin -or $external.base -cne $taskPin){throw 'Wrong input pin.'}
|
|
Push-Location -LiteralPath $taskWorkspace
|
|
try {
|
|
$taskBase=git rev-parse HEAD
|
|
if($LASTEXITCODE -ne 0 -or $taskBase -cne $taskPin){throw 'Wrong source commit.'}
|
|
$status=@(git status --porcelain)
|
|
if($LASTEXITCODE -ne 0 -or $status.Count){throw 'Frozen worktree changed.'}
|
|
$taskRoots=@($enumeration.rootInputs);$taskScopes=@($enumeration.scopes)
|
|
$tracked=@(git ls-files -- @taskRoots @taskScopes)
|
|
if($LASTEXITCODE -ne 0){throw 'Git enumeration failed.'}
|
|
$tracked=@($tracked | ForEach-Object {$_.Replace('\','/')} | Sort-Object -Unique)
|
|
$present=@(rg --files @taskScopes)
|
|
if($LASTEXITCODE -ne 0){throw 'Actual input enumeration failed.'}
|
|
$taskPaths=@(($present+$taskRoots) | ForEach-Object {$_.Replace('\','/')} | Sort-Object -Unique)
|
|
if(@(Compare-Object $tracked $taskPaths).Count -or @(Compare-Object @($enumeration.gitPaths) $tracked).Count){throw 'Frozen input membership changed.'}
|
|
$taskEntries=@($taskPaths | ForEach-Object {$item=Get-Item -LiteralPath $_;[ordered]@{path=$_;bytes=$item.Length;sha256=(Hash-Input $_)}})
|
|
$externalNow=@(foreach($f in $external.files){
|
|
$present=Test-Path -LiteralPath $f.path
|
|
if($present -ne $f.present){throw ('External config presence changed: '+$f.path)}
|
|
if($present){$item=Get-Item -LiteralPath $f.path;$hash=Hash-Input $f.path;if($item.Length -ne $f.bytes -or $hash -cne $f.sha256){throw ('External input changed: '+$f.path)};[ordered]@{path=$f.path;present=$true;bytes=$item.Length;sha256=$hash}}
|
|
else{[ordered]@{path=$f.path;present=$false}}
|
|
})
|
|
$taskRecord=[ordered]@{capturedUtc=[DateTime]::UtcNow.ToString('o');workspace=$taskWorkspace;base=$taskBase;count=$taskEntries.Count;files=$taskEntries;externalInputs=$externalNow;expectedInputsSha256=(Hash-Input (Join-Path $PSScriptRoot 'expected-inputs.json'));enumerationSha256=(Hash-Input (Join-Path $PSScriptRoot 'enumeration.json'))}
|
|
$taskRecord|ConvertTo-Json -Depth 8|Set-Content -LiteralPath $taskOutput -Encoding utf8
|
|
if($taskEntries.Count -ne $pinRecord.count){throw 'Pinned dynamic count changed.'}
|
|
$expected=@{}
|
|
foreach($f in $pinRecord.files){if($expected.ContainsKey($f.path)){throw 'Duplicate pinned input.'};$expected[$f.path]=$f}
|
|
foreach($f in $taskEntries){if(-not $expected.ContainsKey($f.path)){throw 'Unexpected input.'};$old=$expected[$f.path];if($f.bytes -ne $old.bytes -or $f.sha256 -cne $old.sha256){throw ('Input changed: '+$f.path)};$expected.Remove($f.path)}
|
|
if($expected.Count){throw 'Missing input.'}
|
|
if($Stage -ne 'before'){
|
|
$baseline=Get-Content -Raw -LiteralPath (Join-Path $PSScriptRoot 'inputs-complete-before.json')|ConvertFrom-Json
|
|
if($baseline.base -cne $taskPin -or $baseline.count -ne $pinRecord.count -or $baseline.expectedInputsSha256 -cne $taskRecord.expectedInputsSha256 -or $baseline.enumerationSha256 -cne $taskRecord.enumerationSha256){throw 'Baseline binding changed.'}
|
|
}
|
|
Write-Output ('Captured and verified '+$taskEntries.Count+' inputs: '+$Stage)
|
|
} finally {Pop-Location}
|