# rebuild_bootpack_full_seedbox_v1.1.ps1 # Objet : REGENERER COMPLETEMENT bootpack.txt (SEEDBOX). PREVIEW=no-touch. WRITE=SAFE-WRITE. $(if(# Profil vis){ } else { SEEDBOX_MANAGER (scripts /bin/sh ASCII-only }); annexes Windows .ps1 en UTF-8 BOM). # Invariants L0 : GOV_SCRIPT_GATE v1.4 ; SAFE-WRITE v1.1 ; TXT-ONLY v1.0 ; SYNC-MEM-ARCHIVE-RULE v1.0 ; SYNC-GUARD v1.1 param([switch]$Preview,[switch]$Write) function New-Nonce([int]$n=10){ $a=(48..57+65..90+97..122); $s=''; 1..$n|%{ $s+=[char]($a|Get-Random) }; $s } function Write-NoBOM([string]$Path,[string]$Text){ $enc=New-Object System.Text.UTF8Encoding($false); [IO.File]::WriteAllText($Path,$Text,$enc) } function Append-NoBOM([string]$Path,[string]$Text){ $enc=New-Object System.Text.UTF8Encoding($false); [IO.File]::AppendAllText($Path,$Text,$enc) } function Read-FileText([string]$p){ if(Test-Path $p){ [IO.File]::ReadAllText($p,[Text.UTF8Encoding]::new($true)) } else { '' } } function Get-FileSHA256([string]$Path){ if(Test-Path $Path){ (Get-FileHash -Algorithm SHA256 -LiteralPath $Path).Hash } else { '' } } function Compute-TextSHA256([string]$Text){ $sha=[Security.Cryptography.SHA256]::Create(); $bytes=[Text.Encoding]::UTF8.GetBytes($Text); ($sha.ComputeHash($bytes)|%{ $_.ToString('x2') }) -join '' } function Ensure-Parent([string]$Path){ $p=Split-Path -Parent $Path; if($p -and !(Test-Path $p)){ New-Item -ItemType Directory -Force -Path $p|Out-Null } } function Safe-ReplaceFile([string]$Target,[string]$Text){ Ensure-Parent $Target $ts=Get-Date -Format 'yyyyMMdd_HHmmss' $tmp="$Target.$ts.tmp"; $bak="$Target.bak_$ts" Write-NoBOM $tmp $Text $shaTmp=(Get-FileHash -Algorithm SHA256 -LiteralPath $tmp).Hash if(Test-Path $Target){ Copy-Item -LiteralPath $Target -Destination $bak -Force } Move-Item -LiteralPath $tmp -Destination $Target -Force $shaFinal=(Get-FileHash -Algorithm SHA256 -LiteralPath $Target).Hash @{Bak=$bak;ShaTmp=$shaTmp;ShaFinal=$shaFinal} } function Count-KBEntries([string]$kbPath){ $raw=Read-FileText $kbPath $i=$raw.LastIndexOf(']}'); if($i -gt 0){ $raw=$raw.Substring(0,$i+2) } try{ (($raw|ConvertFrom-Json).entries).Count } catch { ([regex]::Matches($raw,'"id"\s*:')).Count } } $Root='\\DS-918\chatgpt\ChatGPT-Gouvernance-Projets\_registry' $BootPack="$Root\bootpack\bootpack.txt" $KBPointerPath="$Root\bootpack\bootpack_paste.txt" $Snapshot="$Root\snapshots\snapshot_{0}.json" -f (Get-Date -Format 'yyyy-MM-dd') $ProfileFile="$Root\profiles\project\SEEDBOX\PROJECT_PROFILE.txt" $LogFile="$Root\logs\registry_activity.log" $L0=@('GOV_SCRIPT_GATE v1.4','SAFE-WRITE v1.1','TXT-ONLY v1.0','SYNC-MEM-ARCHIVE-RULE v1.0','SYNC-GUARD v1.1') if(!(Test-Path $KBPointerPath)){ throw "[BLOCKING] bootpack_paste.txt introuvable : $KBPointerPath" } $kbSha=Get-FileSHA256 $KBPointerPath $kbEntries=Count-KBEntries $KBPointerPath $kbSize=0; if(Test-Path $KBPointerPath){ $kbSize=(Get-Item $KBPointerPath).Length } $kbUpdated=(Get-Item $KBPointerPath).LastWriteTimeUtc.ToString('yyyy-MM-ddTHH:mm:ssZ') $hasSnap=Test-Path $Snapshot $snapSha= if($hasSnap){ Get-FileSHA256 $Snapshot } else { 'MISSING' } $profileTxt=@" PROJECT=SEEDBOX_MANAGER RUNTIME=POSIX_sh ENCODING=.sh=ASCII_only ; .ps1=UTF8_BOM (annexes Windows) CONSTRAINTS=NoAdmin ; UNC ; OneDrivePersonalSeparate "@ $hasProfile = Test-Path $ProfileFile $profilePlannedSha = Compute-TextSHA256 $profileTxt $profileSha = if($hasProfile){ Get-FileSHA256 $ProfileFile } else { "PLANNED:$profilePlannedSha" } $refFiles=@("$Root\REGLES_GOUVERNANCE.txt","$Root\SAFE-WRITE-RULE_v1.1.txt","$Root\GOV_SCRIPT_GATE_v1.4.txt","$Root\TXT-ONLY-POLICY_v1.0.txt") $lines=@(); foreach($f in $refFiles){ $h=Get-FileSHA256 $f; if(!$h){ $h='MISSING' }; $lines += " $f = $h" } $filesShaBlock=($lines -join "`r`n") $memId=(Get-Date).ToString('yyyy-MM-ddTHH:mm:ssK') $nonce=New-Nonce 10 $syncCore=@" MEM_SYNC_ID: $memId RULESET_ACTIVE: $($L0 -join ' ; ') SNAPSHOT_FILE: $Snapshot SNAPSHOT_SHA256: $snapSha FILES_SHA256: $filesShaBlock NONCE: $nonce "@.Trim() $manifestSha=Compute-TextSHA256 $syncCore $syncBody="$syncCore`r`nMANIFEST_SHA256: $manifestSha" $bootpackText=@" [BOOT-PACK] PROJECT: SEEDBOX_MANAGER ROOT: $Root DOCS_FORMAT: TXT-ONLY ENCODING: UTF-8 (no BOM) [POLICY] $($L0 -join "`r`n") [PROJECT_PROFILE_REF] PROFILE_FILE: $ProfileFile PROFILE_SHA256: $profileSha [SYNC_MANIFEST] $syncBody [BUG_KB_JSON_POINTER] Path: $KBPointerPath SHA256: $kbSha Entries: $kbEntries SizeBytes: $kbSize Updated: $kbUpdated [KB_GUARD_ASSERTS] KB-AUTO-ps-5-1-operateur-ternaire-non-supporte-20251018_135633 = covered_by: RULE_PS51_NO_TERNARY v1.0 KB-AUTO-ps-5-1-select-string-sans-recurse-boucler-fichiers-20251018_160307 = covered_by: RULE_SEARCH_NO_RECURSE v1.0 KB-AUTO-join-path-ne-pas-passer-un-tableau-en-childpath-20251018_161141 = covered_by: RULE_SAFE_JOINPATH v1.0 KB-AUTO-safe-write-creer-repertoires-avant-tmp-20251018_160648 = covered_by: RULE_SAFE_WRITE_ENSURE_PARENT v1.0 KB-AUTO-ps-5-1-ps1-en-utf-8-avec-bom-ou-ascii-strict-20251018_162239 = covered_by: RULE_PS1_UTF8_BOM v1.0 KB-AUTO-executionpolicy-allsigned-sur-unc-utiliser-bypass-20251018_165000 = covered_by: RULE_CMD_WRAPPER_BYPASS v1.0 "@.TrimEnd() $plan=@" == PREVIEW :: REBUILD BOOTPACK (SEEDBOX) == Target BootPack : $BootPack PROFILE_FILE : $ProfileFile (SHA=$profileSha) KB Pointer : $KBPointerPath (SHA=$kbSha, Entries=$kbEntries, Size=$kbSize, Updated=$kbUpdated) SNAPSHOT_FILE : $Snapshot (SHA=$snapSha) RULESET_ACTIVE : $($L0 -join ' ; ') MEM_SYNC_ID : $memId MANIFEST_SHA256 : $manifestSha "@ Write-Host $plan if(-not $Write){ Write-Host "Mode PREVIEW : aucune ?criture effectu?e." exit 0 } if(-not $hasSnap){ Ensure-Parent $Snapshot; Write-NoBOM $Snapshot "{}`r`n"; $snapSha=Get-FileSHA256 $Snapshot } if(-not $hasProfile){ Ensure-Parent $ProfileFile; Write-NoBOM $ProfileFile $profileTxt; $profileSha=Get-FileSHA256 $ProfileFile } $memId=(Get-Date).ToString('yyyy-MM-ddTHH:mm:ssK') $syncCore=@" MEM_SYNC_ID: $memId RULESET_ACTIVE: $($L0 -join ' ; ') SNAPSHOT_FILE: $Snapshot SNAPSHOT_SHA256: $snapSha FILES_SHA256: $filesShaBlock NONCE: $nonce "@.Trim() $manifestSha=Compute-TextSHA256 $syncCore $syncBody="$syncCore`r`nMANIFEST_SHA256: $manifestSha" $footer="; DOC-VERSION-FOOTER: rebuild_bootpack_full_seedbox_v1.1.ps1 | "+(Get-Date -Format 'yyyy-MM-dd')+" | SHA="+(Compute-TextSHA256 $bootpackText) $final=($bootpackText.Replace("[SYNC_MANIFEST]", "[SYNC_MANIFEST]`r`n$syncBody").TrimEnd()+"`r`n"+$footer+"`r`n") $result=Safe-ReplaceFile -Target $BootPack -Text $final Write-Host ("Backup : {0}" -f $result.Bak) Write-Host ("SHA tmp/final: {0} / {1}" -f $result.ShaTmp,$result.ShaFinal) $LogFile="$Root\logs\registry_activity.log"; Ensure-Parent $LogFile $logLine=("{0} | action=rebuild_bootpack | project=SEEDBOX | mem_sync_id={1} | manifest_sha={2} | bootpack_sha={3}" -f (Get-Date -Format s), $memId, $manifestSha, $result.ShaFinal) Append-NoBOM $LogFile ($logLine+"`r`n") Write-Host ("SYNC-COMMIT-OK - MEM_SYNC_ID={0}" -f $memId)