Files
ARCADIA-Studio/harness/experiments/scenario-comparators-gui-b10b28c-20260913/spacing/adaptation.diff
T

280 lines
27 KiB
Diff

--- original/oracle/build.ps1
+++ runtime-bound/oracle/build.ps1
@@ -7,7 +7,9 @@
[Parameter(Mandatory=$true,ParameterSetName='Build')][string]$SerdeJsonRlib,
[Parameter(Mandatory=$true,ParameterSetName='Build')][string]$WindowsImportLibDirectory,
[Parameter(Mandatory=$true,ParameterSetName='Build')][string]$Output,
- [Parameter(ParameterSetName='Build')][string]$NativeVerifier=(Join-Path $PSScriptRoot '../../scenario-spacing-native-07e611f-20260913/verify.ps1'),
+ [Parameter(Mandatory=$true,ParameterSetName='Build')][string]$NativeVerifier,
+ [Parameter(Mandatory=$true,ParameterSetName='Build')][ValidatePattern('^[0-9a-f]{64}$')][string]$NativeVerifierSha256,
+ [Parameter(Mandatory=$true,ParameterSetName='Build')][string]$RuntimeDll,
[Parameter(Mandatory=$true,ParameterSetName='Validate')][switch]$ValidateOnly
)
Set-StrictMode -Version Latest
@@ -21,6 +23,16 @@
function Assert-Dependency($Fingerprint,[string]$Name,[UInt64]$Value) {
$edges=@($Fingerprint.deps|Where-Object {$_[1] -ceq $Name})
if($edges.Count -ne 1 -or [UInt64]$edges[0][3] -ne $Value){throw "Cargo dependency fingerprint differs or is ambiguous: $Name"}
+}
+function Select-OracleSources($Inputs,$SourcePaths) {
+ if(@($SourcePaths).Count -ne 5 -or @($SourcePaths|Sort-Object -Unique).Count -ne 5){throw 'Exactly five distinct canonical oracle source paths required'}
+ $selected=@(foreach($path in $SourcePaths){
+ if([IO.Path]::GetFullPath($path) -cne $path){throw 'Oracle source path is not canonical'}
+ $matches=@($Inputs|Where-Object {$_.path -ieq $path})
+ if($matches.Count -ne 1){throw ('Oracle source missing or duplicated in build capture: '+$path)}
+ $matches[0]
+ })
+ return $selected
}
if($ValidateOnly) {
foreach($script in @($PSCommandPath,(Join-Path $PSScriptRoot 'check.ps1'))){
@@ -42,11 +54,30 @@
{Assert-Dependency $sample 'serde_json' ([UInt64]1)},
{Assert-Dependency ('{"deps":[[1,"serde_json",false,1],[2,"serde_json",false,1]]}'|ConvertFrom-Json) 'serde_json' ([UInt64]1)}
)) {try {& $probe|Out-Null} catch {$rejected++;continue};throw 'A fingerprint refusal probe unexpectedly passed.'}
- [ordered]@{status='passed';parsed_scripts=2;positive_cases=4;negative_cases=$rejected;script_sha256=(Get-FileHash -LiteralPath $PSCommandPath -Algorithm SHA256).Hash.ToLowerInvariant();check_script_sha256=(Get-FileHash -LiteralPath (Join-Path $PSScriptRoot 'check.ps1') -Algorithm SHA256).Hash.ToLowerInvariant();compiler_executed=$false;gate_admitted=$false;scope='Syntax and synthetic fingerprint guards only; no dependency selection, compilation or oracle execution'}|ConvertTo-Json
+ $sourcePaths=@('C:\probe\oracle\build.ps1','C:\probe\oracle\check.ps1','C:\probe\oracle\main.rs','C:\probe\incident-workspace.arcadia','C:\verifier\verify.ps1')
+ $sourceRecords=@($sourcePaths|ForEach-Object {[pscustomobject]@{path=$_;bytes=1;sha256=('0'*64)}})
+ if(@(Select-OracleSources $sourceRecords $sourcePaths).Count -ne 5){throw 'Canonical source membership oracle failed'}
+ $sourceRefusals=0
+ $uncanonical=@($sourceRecords|ForEach-Object {[pscustomobject]@{path=$_.path;bytes=$_.bytes;sha256=$_.sha256}})
+ $uncanonical[3].path='C:\probe\oracle\..\incident-workspace.arcadia'
+ $membershipCases=@(
+ @{name='missing_fixture';records=@($sourceRecords|Where-Object {$_.path -ne $sourcePaths[3]})},
+ @{name='unnormalized_fixture';records=$uncanonical},
+ @{name='duplicate_fixture';records=(@($sourceRecords)+@($sourceRecords[3]))}
+ )
+ foreach($case in $membershipCases){
+ $didReject=$false;try{Select-OracleSources $case.records $sourcePaths|Out-Null}catch{$didReject=$true}
+ if(-not $didReject){throw ('Source membership admitted '+$case.name)};$sourceRefusals++
+ }
+ [ordered]@{status='passed';parsed_scripts=2;positive_cases=5;negative_cases=$rejected;source_membership_negative_cases=$sourceRefusals;script_sha256=(Get-FileHash -LiteralPath $PSCommandPath -Algorithm SHA256).Hash.ToLowerInvariant();check_script_sha256=(Get-FileHash -LiteralPath (Join-Path $PSScriptRoot 'check.ps1') -Algorithm SHA256).Hash.ToLowerInvariant();compiler_executed=$false;gate_admitted=$false;scope='Syntax and synthetic fingerprint guards only; no dependency selection, compilation or oracle execution'}|ConvertTo-Json
return
}
-# Reuse the existing native gate verifier; do not reproduce its five-stage parser.
+# Reuse the frozen native verifier; preserve its complete five-stage admission.
+$NativeVerifier=(Get-Item -LiteralPath $NativeVerifier).FullName
+if((Get-FileHash -LiteralPath $NativeVerifier -Algorithm SHA256).Hash.ToLowerInvariant() -cne $NativeVerifierSha256){throw 'Explicit reviewed native verifier changed'}
+$RuntimeDll=(Get-Item -LiteralPath $RuntimeDll).FullName
+if((Get-Item -LiteralPath $RuntimeDll).Length -ne 190464 -or (Get-FileHash -LiteralPath $RuntimeDll -Algorithm SHA256).Hash.ToLowerInvariant() -cne 'aa282fa47bb2c4e210cea5e470cdbdca58568f0be0bc73e404d86ab9cd95ef6a'){throw 'Explicit runtime DLL differs from pinned bytes'}
. $NativeVerifier
$nativePin=$SourcePin
$Gate=(Resolve-Path -LiteralPath $Gate).Path
@@ -94,21 +125,23 @@
$clang=(Get-Command clang -CommandType Application).Source
$gateVersions=Read-NativeJson (Join-Path $Gate 'toolchain-versions.json')
if($rustc -ine $gateVersions.rustcPath -or $clang -ine $gateVersions.clangPath){throw 'Resolved compiler/linker paths differ from the successful gate.'}
-$source=Join-Path $PSScriptRoot 'main.rs'
-$fixture=Join-Path $PSScriptRoot '../incident-workspace.arcadia'
+$source=(Get-Item -LiteralPath (Join-Path $PSScriptRoot 'main.rs')).FullName
+$fixture=(Get-Item -LiteralPath (Join-Path $PSScriptRoot '../incident-workspace.arcadia')).FullName
if((Get-NativeHash $fixture) -cne '74cd2c1dd5eed7eb19895a752bb8ff9ce93655f7638a5312c96f56218568ebb3'){throw 'Embedded original fixture changed.'}
+$oracleSourcePaths=@($PSCommandPath,$source,$fixture,(Join-Path $PSScriptRoot 'check.ps1'),$NativeVerifier)|ForEach-Object {[IO.Path]::GetFullPath($_)}
function Oracle-BuildInputs {
- $paths=@($PSCommandPath,$source,$fixture,(Join-Path $PSScriptRoot 'check.ps1'),$NativeVerifier,$rustc,$clang,$build.externalEnvironmentPath,$desktop.exe,$build.binary.path)
+ $paths=@($oracleSourcePaths)+@($rustc,$clang,$build.externalEnvironmentPath,$desktop.exe,$build.binary.path,$RuntimeDll)
# Complete rustc dependency search inputs, including proc-macro DLLs; exclude test EXEs/logs.
$paths+=@(Get-ChildItem -LiteralPath $deps -File|Where-Object {$_.Extension -in @('.rlib','.rmeta','.dll','.lib','.a')}|ForEach-Object {$_.FullName})
$paths+=@(Get-ChildItem -LiteralPath $native -File -Recurse|ForEach-Object {$_.FullName})
foreach($folder in @($coreFingerprint,$serdeFingerprint,$desktop.folder)){$paths+=@(Get-ChildItem -LiteralPath $folder -File|ForEach-Object {$_.FullName})}
$paths+=@((Join-Path $deps ('oa_core-'+$coreSuffix+'.d')),(Join-Path $deps ('serde_json-'+$serdeSuffix+'.d')),(Join-Path $deps ('arcadia_studio-'+$desktop.suffix+'.d')))
- $paths+=@(Get-ChildItem -LiteralPath $Gate -File|Where-Object {$_.Extension -in @('.json','.ps1','.log')}|ForEach-Object {$_.FullName})
+ $paths+=@(Get-ChildItem -LiteralPath $Gate -File|Where-Object {$_.Extension -in @('.json','.ps1','.log','.md')}|ForEach-Object {$_.FullName})
@($paths|ForEach-Object {[IO.Path]::GetFullPath($_)}|Sort-Object -Unique|ForEach-Object {$item=Get-Item -LiteralPath $_;[ordered]@{path=$item.FullName;bytes=$item.Length;sha256=(Get-NativeHash $item.FullName)}})
}
[void][IO.Directory]::CreateDirectory($Output)
$before=@(Oracle-BuildInputs)
+$sourceRecords=@(Select-OracleSources $before $oracleSourcePaths)
Write-NativeJson (Join-Path $Output 'inputs-before.json') $before
$PSNativeCommandUseErrorActionPreference=$false
$rustcVersion=@(& $rustc --version --verbose 2>&1|ForEach-Object {$_.ToString()});$rustcVersionExit=$LASTEXITCODE
@@ -122,18 +155,28 @@
& $rustc @compilerArgs *> (Join-Path $Output 'compile.log')
$exit=$LASTEXITCODE
$end=[DateTime]::UtcNow.ToString('o')
-$after=@();$failure=$null;$unchanged=$false
+$after=@();$failure=$null;$unchanged=$false;$runtimeSource=$null;$runtimeCopy=$null
try {
$after=@(Oracle-BuildInputs)
+ [void](Select-OracleSources $after $oracleSourcePaths)
Write-NativeJson (Join-Path $Output 'inputs-after.json') $after
Assert-NativeNames @($before|ForEach-Object {$_.path}) @($after|ForEach-Object {$_.path})
$byPath=@{};foreach($f in $before){$byPath[$f.path]=$f}
foreach($f in $after){$old=$byPath[$f.path];if($old.bytes -ne $f.bytes -or $old.sha256 -cne $f.sha256){throw "Build input changed: $($f.path)"}}
Assert-CurrentNativeSource $Gate
[void](Assert-BuildEvidence $Gate)
+ if($exit -eq 0){
+ $runtimeSource=@($before|Where-Object {$_.path -ieq $RuntimeDll})
+ if($runtimeSource.Count -ne 1){throw 'Runtime source missing from build manifest'}
+ $runtimeSource=$runtimeSource[0]
+ $runtimePath=Join-Path $Output 'libunwind.dll'
+ [IO.File]::Copy($RuntimeDll,$runtimePath,$false)
+ $runtimeCopy=[ordered]@{path=$runtimePath;bytes=(Get-Item -LiteralPath $runtimePath).Length;sha256=(Get-NativeHash $runtimePath)}
+ if($runtimeCopy.bytes -ne $runtimeSource.bytes -or $runtimeCopy.sha256 -cne $runtimeSource.sha256){throw 'Adjacent runtime copy differs from captured source'}
+ }
$unchanged=$true
} catch {$failure=$_.Exception.Message}
$binary=if(Test-Path -LiteralPath $exe){$item=Get-Item -LiteralPath $exe;[ordered]@{path=$exe;bytes=$item.Length;sha256=(Get-NativeHash $exe)}}else{$null}
-Write-NativeJson (Join-Path $Output 'build-receipt.json') ([ordered]@{source_commit=$SourcePin;gate=$Gate;gate_build_receipt_sha256=(Get-NativeHash (Join-Path $Gate 'build-receipt.json'));command=@($rustc)+$compilerArgs;start_utc=$start;end_utc=$end;exit_code=$exit;inputs_unchanged=$unchanged;postflight_failure=$failure;binary=$binary;fingerprint_chain=[ordered]@{desktop_fingerprint=$desktop.folder;desktop_exe=$desktop.exe;core=$core;core_fingerprint_value=$coreValue;serde_json=$serde;serde_fingerprint_value=$serdeValue};before_manifest_sha256=(Get-NativeHash (Join-Path $Output 'inputs-before.json'));after_manifest_sha256=if(Test-Path -LiteralPath (Join-Path $Output 'inputs-after.json')){Get-NativeHash (Join-Path $Output 'inputs-after.json')}else{$null};toolchain_sha256=(Get-NativeHash (Join-Path $Output 'toolchain.json'));compile_log_sha256=(Get-NativeHash (Join-Path $Output 'compile.log'));oracle_executed=$false;scope='Standalone oracle compilation only; gate hash plus production desktop→core→serde Cargo fingerprint linkage and unchanged link inputs. No native acceptance.'})
-if($exit -ne 0 -or -not $unchanged -or $null -eq $binary -or $binary.bytes -le 0){throw 'Oracle build or provenance failed; preserve all output.'}
+Write-NativeJson (Join-Path $Output 'build-receipt.json') ([ordered]@{schema='scenario_spacing_oracle_build_v2';source_commit=$SourcePin;native_verifier=[ordered]@{path=$NativeVerifier;sha256=$NativeVerifierSha256};runtime_source=$runtimeSource;runtime=$runtimeCopy;source_files=$sourceRecords;gate=$Gate;gate_build_receipt_sha256=(Get-NativeHash (Join-Path $Gate 'build-receipt.json'));command=@($rustc)+$compilerArgs;start_utc=$start;end_utc=$end;exit_code=$exit;inputs_unchanged=$unchanged;postflight_failure=$failure;binary=$binary;fingerprint_chain=[ordered]@{desktop_fingerprint=$desktop.folder;desktop_exe=$desktop.exe;core=$core;core_fingerprint_value=$coreValue;serde_json=$serde;serde_fingerprint_value=$serdeValue};before_manifest_sha256=(Get-NativeHash (Join-Path $Output 'inputs-before.json'));after_manifest_sha256=if(Test-Path -LiteralPath (Join-Path $Output 'inputs-after.json')){Get-NativeHash (Join-Path $Output 'inputs-after.json')}else{$null};toolchain_sha256=(Get-NativeHash (Join-Path $Output 'toolchain.json'));compile_log_sha256=(Get-NativeHash (Join-Path $Output 'compile.log'));oracle_executed=$false;scope='Standalone oracle compilation only; gate hash plus production desktop -> core -> serde Cargo fingerprint linkage and unchanged link inputs. No native acceptance.'})
+if($exit -ne 0 -or -not $unchanged -or $null -eq $binary -or $binary.bytes -le 0 -or $null -eq $runtimeCopy -or $null -ne $failure){throw 'Oracle build or provenance failed; preserve all output.'}
Write-Output 'Standalone oracle built and hash-bound; oracle and native workflows have not run.'
--- original/oracle/check.ps1
+++ runtime-bound/oracle/check.ps1
@@ -1,56 +1,116 @@
#Requires -Version 7.0
-[CmdletBinding()]
+[CmdletBinding(DefaultParameterSetName='Run')]
param(
- [Parameter(Mandatory=$true)][string]$OracleExe,
- [Parameter(Mandatory=$true)][ValidatePattern('^[0-9a-f]{64}$')][string]$OracleSha256,
- [Parameter(Mandatory=$true)][string]$BuildReceipt,
- [Parameter(Mandatory=$true)][ValidatePattern('^[0-9a-f]{64}$')][string]$BuildReceiptSha256,
- [Parameter(Mandatory=$true)][ValidateSet('self-check','same','repair-c','lane','message')][string]$Mode,
- [Parameter(Mandatory=$true)][string]$Baseline,
+ [Parameter(Mandatory=$true,ParameterSetName='Run')][ValidatePattern('^[0-9a-f]{40}$')][string]$SourcePin,
+ [Parameter(Mandatory=$true,ParameterSetName='Run')][string]$OracleExe,
+ [Parameter(Mandatory=$true,ParameterSetName='Run')][ValidatePattern('^[0-9a-f]{64}$')][string]$OracleSha256,
+ [Parameter(Mandatory=$true,ParameterSetName='Run')][string]$BuildReceipt,
+ [Parameter(Mandatory=$true,ParameterSetName='Run')][ValidatePattern('^[0-9a-f]{64}$')][string]$BuildReceiptSha256,
+ [Parameter(Mandatory=$true,ParameterSetName='Run')][ValidateSet('self-check','same','repair-c','lane','message')][string]$Mode,
+ [Parameter(Mandatory=$true,ParameterSetName='Run')][string]$Baseline,
[string]$Actual,
- [Parameter(Mandatory=$true)][string]$Output,
+ [Parameter(Mandatory=$true,ParameterSetName='Run')][string]$Output,
[string]$View,
[string]$Target,
- [string]$Coordinate
+ [string]$Coordinate,
+ [Parameter(Mandatory=$true,ParameterSetName='Validate')][switch]$ValidateOnly
)
Set-StrictMode -Version Latest
$ErrorActionPreference='Stop'
function Hash([string]$Path){(Get-FileHash -LiteralPath $Path -Algorithm SHA256).Hash.ToLowerInvariant()}
function Record([string]$Path){$file=Get-Item -LiteralPath $Path;[ordered]@{path=$file.FullName;bytes=$file.Length;sha256=(Hash $file.FullName)}}
function Write-NewJson([string]$Path,$Value){$stream=[IO.File]::Open($Path,[IO.FileMode]::CreateNew,[IO.FileAccess]::Write,[IO.FileShare]::Read);try{$bytes=[Text.UTF8Encoding]::new($false).GetBytes(($Value|ConvertTo-Json -Depth 12)+"`n");$stream.Write($bytes,0,$bytes.Length);$stream.Flush($true)}finally{$stream.Dispose()}}
+function Assert-AcceptedBuild($Build,$ExeRecord,$RuntimeRecord,[string]$ExpectedSourcePin) {
+ if($ExpectedSourcePin -cnotmatch '^[0-9a-f]{40}$'){throw 'Explicit reviewed source pin required'}
+ if($Build.schema -cne 'scenario_spacing_oracle_build_v2' -or $Build.source_commit -cne $ExpectedSourcePin -or $Build.exit_code -ne 0 -or -not $Build.inputs_unchanged -or $null -ne $Build.postflight_failure){throw 'Successful spacing-oracle build for the explicit reviewed source required'}
+ if($null -eq $Build.binary -or $Build.binary.path -ine $ExeRecord.path -or $Build.binary.bytes -ne $ExeRecord.bytes -or $Build.binary.sha256 -cne $ExeRecord.sha256 -or $ExeRecord.bytes -le 0){throw 'Receipt does not describe supplied executable'}
+ $adjacent=Join-Path (Split-Path -Parent $ExeRecord.path) 'libunwind.dll'
+ if($null -eq $Build.runtime -or $null -eq $Build.runtime_source -or $Build.runtime.path -ine $adjacent -or $RuntimeRecord.path -ine $adjacent){throw 'Receipt must bind the actual adjacent runtime DLL'}
+ foreach($r in @($Build.runtime_source,$Build.runtime,$RuntimeRecord)){
+ if($r.bytes -ne 190464 -or $r.sha256 -cne 'aa282fa47bb2c4e210cea5e470cdbdca58568f0be0bc73e404d86ab9cd95ef6a'){throw 'Runtime DLL differs from exact pinned bytes'}
+ }
+}
+function Assert-Records($Files){foreach($f in $Files){$current=Record $f.path;if($current.bytes -ne $f.bytes -or $current.sha256 -cne $f.sha256){throw ('Changed input: '+$f.path)}}}
+function Read-Json([string]$Path){Get-Content -Raw -LiteralPath $Path|ConvertFrom-Json}
+if($ValidateOnly){
+ $tokens=$null;$errors=$null;[void][Management.Automation.Language.Parser]::ParseFile($PSCommandPath,[ref]$tokens,[ref]$errors);if(@($errors).Count){throw ($errors|Out-String)}
+ $sample=[ordered]@{schema='scenario_spacing_oracle_build_v2';source_commit='8bf7607a3f3b53db0c36364f54f57674c64ea2f1';exit_code=0;inputs_unchanged=$true;postflight_failure=$null;binary=@{path='C:\probe\oracle.exe';bytes=100;sha256=('1'*64)};runtime=@{path='C:\probe\libunwind.dll';bytes=190464;sha256='aa282fa47bb2c4e210cea5e470cdbdca58568f0be0bc73e404d86ab9cd95ef6a'};runtime_source=@{path='C:\toolchain\libunwind.dll';bytes=190464;sha256='aa282fa47bb2c4e210cea5e470cdbdca58568f0be0bc73e404d86ab9cd95ef6a'}}
+ $expectedPin=$sample.source_commit
+ $json=$sample|ConvertTo-Json -Depth 8;$exe=$sample.binary;$runtime=$sample.runtime
+ Assert-AcceptedBuild ($json|ConvertFrom-Json) $exe $runtime $expectedPin
+ $revised=$json|ConvertFrom-Json;$revised.source_commit=('3'*40);Assert-AcceptedBuild $revised $exe $runtime ('3'*40)
+ $cases=@(
+ @{name='failed_compile';change={param($b)$b.exit_code=1}},
+ @{name='changed_build_inputs';change={param($b)$b.inputs_unchanged=$false}},
+ @{name='postflight_failure';change={param($b)$b.postflight_failure='changed'}},
+ @{name='wrong_source';change={param($b)$b.source_commit=('0'*40)}},
+ @{name='legacy_receipt';change={param($b)$b.schema='old'}},
+ @{name='different_exe';change={param($b)$b.binary.sha256=('2'*64)}},
+ @{name='different_exe_size';change={param($b)$b.binary.bytes=101}},
+ @{name='different_exe_path';change={param($b)$b.binary.path='C:\other\oracle.exe'}},
+ @{name='missing_runtime';change={param($b)$b.runtime=$null}},
+ @{name='nonadjacent_runtime';change={param($b)$b.runtime.path='C:\other\libunwind.dll'}},
+ @{name='wrong_runtime_hash';change={param($b)$b.runtime.sha256=('2'*64)}},
+ @{name='wrong_runtime_size';change={param($b)$b.runtime.bytes=190463}},
+ @{name='wrong_runtime_source';change={param($b)$b.runtime_source.sha256=('2'*64)}}
+ )
+ $passed=@();foreach($case in $cases){$b=$json|ConvertFrom-Json;& $case.change $b;$rejected=$false;try{Assert-AcceptedBuild $b $exe $runtime $expectedPin}catch{$rejected=$true};if(-not $rejected){throw ('Guard admitted '+$case.name)};$passed+=@($case.name)}
+ foreach($change in @('path','sha256','bytes')){
+ $r=($sample.runtime|ConvertTo-Json|ConvertFrom-Json)
+ switch($change){'path'{$r.path='C:\other\libunwind.dll'}'sha256'{$r.sha256=('3'*64)}'bytes'{$r.bytes=1}}
+ $rejected=$false;try{Assert-AcceptedBuild ($json|ConvertFrom-Json) $exe $r $expectedPin}catch{$rejected=$true};if(-not $rejected){throw 'Current runtime mutation admitted'};$passed+=@('current_runtime_'+$change)
+ }
+ $badPinRejected=$false;try{Assert-AcceptedBuild ($json|ConvertFrom-Json) $exe $runtime ''}catch{$badPinRejected=$true};if(-not $badPinRejected){throw 'Missing expected source pin admitted'};$passed+=@('missing_expected_source_pin')
+ [ordered]@{status='passed';positive_cases=2;negative_cases=$passed;compiler_executed=$false;oracle_executed=$false;scope='Pure production receipt/runtime admission function with synthetic metadata; no gate or binary execution'}|ConvertTo-Json -Depth 8
+ return
+}
if(Test-Path -LiteralPath $Output){throw 'Preserve previous oracle evidence; choose a new output directory.'}
if((Hash $OracleExe) -cne $OracleSha256 -or (Hash $BuildReceipt) -cne $BuildReceiptSha256){throw 'Reviewed oracle binary/build receipt binding differs.'}
-$paths=@($OracleExe,$BuildReceipt,$PSCommandPath,(Join-Path $PSScriptRoot 'main.rs'),(Join-Path $PSScriptRoot '../incident-workspace.arcadia'),$Baseline)
-if($Mode -ne 'self-check') {if([string]::IsNullOrWhiteSpace($Actual)){throw 'Actual checkpoint is required.'};$paths+=@($Actual)}
-$before=@($paths|ForEach-Object {Record $_})
-$base=(Get-Item -LiteralPath $Baseline).FullName
$exe=(Get-Item -LiteralPath $OracleExe).FullName
-$outputPath=[IO.Path]::GetFullPath($Output)
-[void][IO.Directory]::CreateDirectory($outputPath)
-[IO.File]::Copy($base,(Join-Path $outputPath 'baseline.arcadia'),$false)
-$argsForOracle=@($Mode,$base)
-if($Mode -ne 'self-check'){
- $actualPath=(Get-Item -LiteralPath $Actual).FullName
- [IO.File]::Copy($actualPath,(Join-Path $outputPath 'actual.arcadia'),$false)
- $argsForOracle+=@($actualPath)
+$build=Read-Json $BuildReceipt
+$runtime=Join-Path (Split-Path -Parent $exe) 'libunwind.dll'
+Assert-AcceptedBuild $build (Record $exe) (Record $runtime) $SourcePin
+$buildDir=Split-Path -Parent ((Get-Item -LiteralPath $BuildReceipt).FullName)
+$proof=@(@{name='inputs-before.json';sha=$build.before_manifest_sha256},@{name='inputs-after.json';sha=$build.after_manifest_sha256},@{name='toolchain.json';sha=$build.toolchain_sha256},@{name='compile.log';sha=$build.compile_log_sha256})
+foreach($f in $proof){if((Hash (Join-Path $buildDir $f.name)) -cne $f.sha){throw 'Build proof file changed'}}
+$buildBefore=@(Read-Json (Join-Path $buildDir 'inputs-before.json'));$buildAfter=@(Read-Json (Join-Path $buildDir 'inputs-after.json'))
+if(($buildBefore|ConvertTo-Json -Depth 8 -Compress) -cne ($buildAfter|ConvertTo-Json -Depth 8 -Compress)){throw 'Build input manifests differ'}
+$byPath=@{};foreach($f in $buildBefore){if($byPath.ContainsKey($f.path)){throw 'Duplicate build manifest input'};$byPath[$f.path]=$f}
+foreach($f in @($build.source_files)+@($build.runtime_source)){
+ if(-not $byPath.ContainsKey($f.path) -or $byPath[$f.path].bytes -ne $f.bytes -or $byPath[$f.path].sha256 -cne $f.sha256){throw 'Source/runtime record not bound by successful build'}
}
-$argsForOracle+=@((Join-Path $outputPath 'project-comparison'))
-if($Mode -in @('lane','message')){
+$localSource=@($PSCommandPath,(Join-Path $PSScriptRoot 'build.ps1'),(Join-Path $PSScriptRoot 'main.rs'),(Join-Path $PSScriptRoot '../incident-workspace.arcadia'))
+foreach($p in $localSource){$path=(Get-Item -LiteralPath $p).FullName;$match=@($build.source_files|Where-Object {$_.path -ieq $path});if($match.Count -ne 1){throw 'Current oracle source is not the build-bound source'}}
+Assert-Records $build.source_files
+if((Hash (Join-Path $build.gate 'build-receipt.json')) -cne $build.gate_build_receipt_sha256){throw 'Accepted GUI gate receipt changed'}
+# Runtime source is historical build input; the actual copied DLL is the loaded artifact.
+$paths=@($exe,$runtime,$BuildReceipt,$Baseline)+$localSource+@($build.source_files|ForEach-Object path)+@($proof|ForEach-Object {Join-Path $buildDir $_.name})+@((Join-Path $build.gate 'build-receipt.json'))
+if($Mode -ne 'self-check'){if([string]::IsNullOrWhiteSpace($Actual)){throw 'Actual checkpoint is required.'};$paths+=@($Actual)}
+$extra=@();if($Mode -in @('lane','message')){
foreach($value in @($View,$Target,$Coordinate)){if([string]::IsNullOrWhiteSpace($value)){throw 'Spacing comparison needs independently chosen View, Target and Coordinate.'}}
- $argsForOracle+=@($View,$Target,$Coordinate)
-} elseif($View -or $Target -or $Coordinate){throw 'Unexpected spacing parameters for this comparison mode.'}
-$start=[DateTime]::UtcNow.ToString('o')
+ $extra=@($View,$Target,$Coordinate)
+}elseif($View -or $Target -or $Coordinate){throw 'Unexpected spacing parameters for this comparison mode.'}
+$before=@($paths|ForEach-Object {(Get-Item -LiteralPath $_).FullName}|Sort-Object -Unique|ForEach-Object {Record $_})
+$outputPath=[IO.Path]::GetFullPath($Output);[void][IO.Directory]::CreateDirectory($outputPath)
+$base=(Get-Item -LiteralPath $Baseline).FullName;$baseCopy=Join-Path $outputPath 'baseline.arcadia';[IO.File]::Copy($base,$baseCopy,$false)
+$argsForOracle=@($Mode,$baseCopy)
+if($Mode -ne 'self-check'){$actualPath=(Get-Item -LiteralPath $Actual).FullName;$actualCopy=Join-Path $outputPath 'actual.arcadia';[IO.File]::Copy($actualPath,$actualCopy,$false);$argsForOracle+=@($actualCopy)}
+$argsForOracle+=@((Join-Path $outputPath 'project-comparison'))+$extra
+Write-NewJson (Join-Path $outputPath 'inputs-before.json') $before
+Write-NewJson (Join-Path $outputPath 'request.json') ([ordered]@{mode=$Mode;view=$View;target=$Target;coordinate=$Coordinate;expected_origin='Predetermined independently from actual pointer/scale and baseline; never learned from Actual'})
+$start=[DateTime]::UtcNow.ToString('o');$exit=$null;$failure=$null;$unchanged=$false;$semanticPass=$false
$PSNativeCommandUseErrorActionPreference=$false
-& $exe @argsForOracle *> (Join-Path $outputPath 'oracle.log')
-$exit=$LASTEXITCODE
-$unchanged=$true
-foreach($file in $before){if((Get-Item -LiteralPath $file.path).Length -ne $file.bytes -or (Hash $file.path) -cne $file.sha256){$unchanged=$false}}
-if((Hash (Join-Path $outputPath 'baseline.arcadia')) -cne (Hash $base)){$unchanged=$false}
-if($Mode -ne 'self-check' -and (Hash (Join-Path $outputPath 'actual.arcadia')) -cne (Hash $actualPath)){$unchanged=$false}
-$result=Join-Path $outputPath ('project-comparison/'+$(if($Mode -eq 'self-check'){'self-check.json'}else{'comparison.json'}))
-$semanticPass=$false
-if(Test-Path -LiteralPath $result){$record=Get-Content -Raw -LiteralPath $result|ConvertFrom-Json;$semanticPass=$record.status -ceq 'passed';if($Mode -ne 'self-check'){$semanticPass=$semanticPass -and $record.full_project_exact}}
+try {& $exe @argsForOracle *> (Join-Path $outputPath 'oracle.log');$exit=$LASTEXITCODE}catch{$failure=$_.Exception.Message}
+try {
+ Assert-Records $before
+ Assert-AcceptedBuild (Read-Json $BuildReceipt) (Record $exe) (Record $runtime) $SourcePin
+ if((Hash $baseCopy) -cne (Hash $base)){throw 'Baseline copy changed'}
+ if($Mode -ne 'self-check' -and (Hash $actualCopy) -cne (Hash $actualPath)){throw 'Actual copy changed'}
+ $after=@($before|ForEach-Object {Record $_.path});Write-NewJson (Join-Path $outputPath 'inputs-after.json') $after;$unchanged=$true
+ $result=Join-Path $outputPath ('project-comparison/'+$(if($Mode -eq 'self-check'){'self-check.json'}else{'comparison.json'}))
+ if(Test-Path -LiteralPath $result){$record=Read-Json $result;$semanticPass=$record.status -ceq 'passed';if($Mode -ne 'self-check'){$semanticPass=$semanticPass -and $record.mode -ceq $Mode -and $record.full_project_exact}}
+}catch{if($null -eq $failure){$failure=$_.Exception.Message}}
$files=@(Get-ChildItem -LiteralPath $outputPath -File -Recurse|ForEach-Object {Record $_.FullName})
-Write-NewJson (Join-Path $outputPath 'receipt.json') ([ordered]@{start_utc=$start;end_utc=[DateTime]::UtcNow.ToString('o');command=@($exe)+$argsForOracle;mode=$Mode;oracle_exit_code=$exit;inputs_unchanged=$unchanged;semantic_pass=$semanticPass;inputs_before=$before;output_files=$files;scope='External parsed saved-source Project comparison only; no native action or runtime/history inspection'})
-if($exit -ne 0 -or -not $unchanged -or -not $semanticPass){throw 'Oracle comparison or input stability failed; preserve receipt and raw output.'}
+Write-NewJson (Join-Path $outputPath 'receipt.json') ([ordered]@{schema='scenario_spacing_oracle_run_v2';source_commit=$build.source_commit;start_utc=$start;end_utc=[DateTime]::UtcNow.ToString('o');command=@($exe)+$argsForOracle;mode=$Mode;oracle_exit_code=$exit;failure=$failure;inputs_unchanged=$unchanged;semantic_pass=$semanticPass;oracle_sha256=$OracleSha256;build_receipt_sha256=$BuildReceiptSha256;runtime_binding=$build.runtime;inputs_before=$before;output_files=$files;scope='External admitted saved-source Project comparison only; no native action or runtime/history inspection'})
+if($exit -ne 0 -or -not $unchanged -or -not $semanticPass -or $null -ne $failure){throw 'Oracle comparison or input stability failed; preserve receipt and raw output.'}
Write-Output 'Saved-source oracle passed; runtime and native action evidence remain separate.'