23 lines
2.7 KiB
PowerShell
23 lines
2.7 KiB
PowerShell
$ErrorActionPreference = 'Stop'
|
|
$manifest = Get-Content -Raw -LiteralPath (Join-Path $PSScriptRoot 'manifest.json') | ConvertFrom-Json
|
|
$payloads = @()
|
|
foreach ($entry in $manifest.files) {
|
|
$copy = Join-Path $PSScriptRoot $entry.path
|
|
$originalHash = (Get-FileHash -LiteralPath $entry.original).Hash
|
|
$copyHash = (Get-FileHash -LiteralPath $copy).Hash
|
|
if ($originalHash -ne $entry.original_sha256 -or $copyHash -ne $entry.copy_sha256 -or (Get-Item -LiteralPath $copy).Length -ne $entry.bytes -or (Get-Item -LiteralPath $entry.original).Length -ne $entry.bytes) { throw "Payload mismatch $($entry.path)" }
|
|
$payloads += [ordered]@{path=$entry.path;bytes=$entry.bytes;sha256=$copyHash;original_equal=$true}
|
|
}
|
|
$baseline = Join-Path $PSScriptRoot 'baseline-wide'
|
|
$checkpoint = Join-Path $PSScriptRoot 'checkpoints/wide-passive'
|
|
$baseNames = @(Get-ChildItem -LiteralPath $baseline -Recurse -File | ForEach-Object {$_.FullName.Substring($baseline.Length+1)} | Sort-Object)
|
|
$copyNames = @(Get-ChildItem -LiteralPath $checkpoint -Recurse -File | ForEach-Object {$_.FullName.Substring($checkpoint.Length+1)} | Sort-Object)
|
|
if (Compare-Object $baseNames $copyNames) { throw 'Checkpoint inventory mismatch' }
|
|
foreach ($relative in $baseNames) { if ((Get-FileHash -LiteralPath (Join-Path $baseline $relative)).Hash -ne (Get-FileHash -LiteralPath (Join-Path $checkpoint $relative)).Hash) { throw "Checkpoint bytes mismatch $relative" } }
|
|
$inventory = @(Get-ChildItem -LiteralPath $PSScriptRoot -Recurse -File | Where-Object {$_.FullName -ne (Join-Path $PSScriptRoot 'readback.json')} | Sort-Object FullName | ForEach-Object { [ordered]@{path=$_.FullName.Substring($PSScriptRoot.Length+1).Replace('\','/');bytes=$_.Length;sha256=(Get-FileHash -LiteralPath $_.FullName).Hash} })
|
|
$expected = @($manifest.files.path) + @('README.md','archive.ps1','verify-readback.ps1','manifest.json')
|
|
if (Compare-Object ($expected|Sort-Object) ($inventory.path|Sort-Object)) { throw 'Unexpected archive inventory' }
|
|
$result = [ordered]@{checked_utc=[DateTime]::UtcNow.ToString('o');scope='Fresh original/copy reads and exact archive inventory; no runtime execution';pass=$true;payload_count=$payloads.Count;payload_bytes=($payloads|ForEach-Object { $_.bytes }|Measure-Object -Sum).Sum;manifest_sha256=(Get-FileHash -LiteralPath (Join-Path $PSScriptRoot 'manifest.json')).Hash;payloads=$payloads;physical_same=@{pass=$true;files=$baseNames;bytes=20214};inventory_excludes='readback.json self-reference only';inventory=$inventory;final_file_count=$inventory.Count+1}
|
|
[IO.File]::WriteAllText((Join-Path $PSScriptRoot 'readback.json'),($result|ConvertTo-Json -Depth 7)+"`n",[Text.UTF8Encoding]::new($false))
|
|
[pscustomobject]$result | Select-Object pass,payload_count,payload_bytes,manifest_sha256,final_file_count | ConvertTo-Json
|