????# gov_pipeline_doctor_ultra_min_v1.ps1 # Minimal pointer sanity (Path/SHA/Entries/Size) - no acceptance, no post-hook. # ASCII-only, PS 5.1-safe, no here-strings, line-by-line parsing. param( [string]$Root = "\\\\DS-918\\chatgpt\\ChatGPT-Gouvernance-Projets\\_registry", [switch]$Utf8Console ) if($Utf8Console){ try{ [Console]::OutputEncoding = [Text.Encoding]::UTF8 }catch{} } function Exists([string]$p){ return (-not [string]::IsNullOrWhiteSpace($p)) -and (Test-Path -LiteralPath $p) } function Read-Text([string]$p){ if(-not (Exists $p)){ return "" } try{ return Get-Content -LiteralPath $p -Raw -Encoding UTF8 }catch{ return (Get-Content -LiteralPath $p -Raw) } } function To-IntSafe([object]$v){ try{ return [int]$v }catch{ return -1 } } function Count-EntriesFromJson([string]$json){ if([string]::IsNullOrWhiteSpace($json)){ return -1 } if($json.Length -gt 0 -and ([int]$json[0] -eq 0xFEFF)){ $json = $json.Substring(1) } try{ $o = $json | ConvertFrom-Json; if($o -and $o.PSObject.Properties.Name -contains "entries"){ return @($o.entries).Count } }catch{} try{ $count=0; $i=0; while($true){ $j = $json.IndexOf("\"id\"",$i); if($j -lt 0){ break } $count++; $i=$j+4 } return $count }catch{} return -1 } function CleanHex([string]$s){ if([string]::IsNullOrWhiteSpace($s)){ return "" } $r = ""; foreach($c in $s.ToCharArray()){ if( ("0" -le $c -and $c -le "9") -or ("A" -le $c -and $c -le "F") -or ("a" -le $c -and $c -le "f") ){ $r += $c } } return $r.ToUpperInvariant() } $bpFile = Join-Path $Root "bootpack\\bootpack.txt" $pasteFile = Join-Path $Root "bootpack\\bootpack_paste.txt" Write-Host "== GOV PIPELINE :: DOCTOR-ULTRA-MIN v1 ==" Write-Host ("Root : {0}" -f $Root) if(-not (Exists $bpFile)){ Write-Host ("[FATAL] missing bootpack.txt: {0}" -f $bpFile); exit 3 } if(-not (Exists $pasteFile)){ Write-Host ("[FATAL] missing bootpack_paste.txt: {0}" -f $pasteFile); exit 3 } $rawBP = Read-Text $bpFile $rawPP = Read-Text $pasteFile try{ $psSha = (Get-FileHash -Algorithm SHA256 -LiteralPath $pasteFile).Hash.ToUpperInvariant() }catch{ $psSha = "" } try{ $psSize = (Get-Item -LiteralPath $pasteFile).Length }catch{ $psSize = -1 } $psEnt = Count-EntriesFromJson $rawPP # pointer parsing $P_path = ""; $P_sha = ""; $P_ent = -1; $P_sz = -1 $norm = $rawBP -replace "`r`n","`n" $lines = $norm -split "`n" $inBlk = $false foreach($ln in $lines){ $t = $ln.Trim() if($t -ceq "[BUG_KB_JSON_POINTER]"){ $inBlk = $true; continue } if($inBlk){ if($t.StartsWith("[")){ $inBlk = $false; break } if($t.Length -gt 0){ $k = $t.IndexOf(":"); if($k -ge 0){ $name = $t.Substring(0,$k).Trim() $val = $t.Substring($k+1).Trim() if($name -ieq "Path"){ $P_path = $val } elseif($name -ieq "SHA256"){ $P_sha = CleanHex $val } elseif($name -ieq "Entries"){ $P_ent = To-IntSafe $val } elseif($name -ieq "SizeBytes"){ $P_sz = To-IntSafe $val } } } } } $eqPath = ($P_path -ceq $pasteFile) $eqSha = ($P_sha -eq $psSha) $eqEnt = ($P_ent -eq $psEnt) $eqSize = ($P_sz -eq [int]$psSize) Write-Host ("PTR : path==paste={0} sha==paste={1} entries==paste={2} size==paste={3}" -f $eqPath,$eqSha,$eqEnt,$eqSize) if($eqPath -and $eqSha -and $eqEnt -and $eqSize){ Write-Host "Result: PASS"; exit 0 } if(-not $eqPath){ Write-Host " - Pointer.Path mismatch" } if(-not $eqSha ){ Write-Host " - Pointer.SHA mismatch" } if(-not $eqEnt ){ Write-Host " - Pointer.Entries mismatch" } if(-not $eqSize){ Write-Host " - Pointer.SizeBytes mismatch" } Write-Host "Result: FAIL"; exit 2