# SonPatch.ps1 — MnemosyneC Stage-B cure · BP085 # Model: Sonnet 4.6 # Liana Banyan Cooperative param([switch]$WhatIf) $skipHashCheck = $false # SEG-5 backfilled real SHA256 — hash check active $logPath = "$env:TEMP\SonPatch.log" # ----------------------------------------------------------------------------- # STEP 1 — Init logging # ----------------------------------------------------------------------------- $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" $backupTag = Get-Date -Format "yyyyMMdd_HHmmss" try { Add-Content $logPath "[$timestamp] SonPatch BP085 started" Write-Host "SonPatch BP085 — starting..." -ForegroundColor Cyan } catch { $errMsg = $_.Exception.Message Write-Host "FAILED to init log: $errMsg" -ForegroundColor Red exit 1 } # ----------------------------------------------------------------------------- # STEP 2 — Detect and kill MnemosyneC processes # ----------------------------------------------------------------------------- try { $processNames = @("MnemosyneC", "mnemosynec") $killed = $false foreach ($pName in $processNames) { $procs = Get-Process -Name $pName -ErrorAction SilentlyContinue foreach ($proc in $procs) { if ($WhatIf) { Write-Host "What if: Stop-Process $($proc.Name) PID $($proc.Id)" } else { Stop-Process -Id $proc.Id -Force; Add-Content $logPath "[STEP2] Killed $($proc.Name) PID $($proc.Id)"; $killed = $true } } } if (-not $killed) { Add-Content $logPath "[STEP2] No running MnemosyneC process detected — continuing" } if (-not $WhatIf) { Start-Sleep -Seconds 2 } } catch { $errMsg = $_.Exception.Message; Add-Content $logPath "[ERROR] Step2: $errMsg"; Write-Host "FAILED: $errMsg" -ForegroundColor Red; exit 1 } # ----------------------------------------------------------------------------- # STEP 3 — Detect current install state # ----------------------------------------------------------------------------- try { # Check registry for installed version $regPaths = @( "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\", "HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\" ) $installedVersion = $null foreach ($regPath in $regPaths) { if (Test-Path $regPath) { Get-ChildItem $regPath | ForEach-Object { $displayName = (Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue).DisplayName if ($displayName -like "*MnemosyneC*") { $installedVersion = (Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue).DisplayVersion } } } } if ($installedVersion) { Add-Content $logPath "[STEP3] Installed version: $installedVersion" } else { Add-Content $logPath "[STEP3] No MnemosyneC registry entry found" } # Check both capitalizations of profile folder (BP083 canon: lowercase) $profilePaths = @("$env:APPDATA\mnemosynec", "$env:APPDATA\MnemosyneC") $profileFolder = $null foreach ($p in $profilePaths) { if (Test-Path $p) { $profileFolder = $p; break } } if ($profileFolder) { $lastMod = (Get-Item $profileFolder).LastWriteTime Add-Content $logPath "[STEP3] Profile folder found: $profileFolder (last modified: $lastMod)" } else { Add-Content $logPath "[STEP3] No profile folder found — fresh install path" } } catch { $errMsg = $_.Exception.Message; Add-Content $logPath "[ERROR] Step3: $errMsg"; Write-Host "FAILED: $errMsg" -ForegroundColor Red; exit 1 } # ----------------------------------------------------------------------------- # STEP 4 — Stage-B detection logic # ----------------------------------------------------------------------------- $stageB = $false try { if ($profileFolder) { # Condition A: JSON with non-completed lifecycle stage $jsonFiles = Get-ChildItem $profileFolder -Filter "*.json" -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.Name -match "config|profile" } foreach ($jf in $jsonFiles) { $content = Get-Content $jf.FullName -Raw -ErrorAction SilentlyContinue if ($content -match '"(lifecycleStage|onboardingStage|stage)"\s*:\s*"(?!complete|completed|done|active)') { $stageB = $true Add-Content $logPath "[STEP4] Stage-B detected via Condition A: $($jf.Name) has non-completed lifecycle stage" break } } # Condition B: folder older than 7 days with no completed/active flag anywhere if (-not $stageB) { $lastMod = (Get-Item $profileFolder).LastWriteTime $agedays = ((Get-Date) - $lastMod).TotalDays $allContent = Get-ChildItem $profileFolder -Recurse -ErrorAction SilentlyContinue | Get-Content -Raw -ErrorAction SilentlyContinue | Out-String if ($agedays -gt 7 -and $allContent -notmatch '"(completed|active)"') { $stageB = $true Add-Content $logPath "[STEP4] Stage-B detected via Condition B: profile $([math]::Round($agedays,1)) days old, no completed/active flag" } } } if (-not $stageB) { Add-Content $logPath "[STEP4] Stage-B not detected — proceeding to clean install only." } } catch { $errMsg = $_.Exception.Message; Add-Content $logPath "[ERROR] Step4: $errMsg"; Write-Host "FAILED: $errMsg" -ForegroundColor Red; exit 1 } # ----------------------------------------------------------------------------- # STEP 5 — Backup then wipe # ----------------------------------------------------------------------------- try { if ($profileFolder) { $backupDest = "$env:APPDATA\mnemosynec.bak.$backupTag" if ($WhatIf) { Write-Host "What if: Copy-Item -Recurse '$profileFolder' to '$backupDest'" Write-Host "What if: Remove-Item -Recurse -Force '$profileFolder'" } else { Copy-Item -Path $profileFolder -Destination $backupDest -Recurse -Force if (Test-Path $backupDest) { Add-Content $logPath "[STEP5] Backup created at: $backupDest" Remove-Item -Path $profileFolder -Recurse -Force Add-Content $logPath "[STEP5] Profile wiped. Backup at: $backupDest" } else { Add-Content $logPath "[ERROR] Backup verification failed — aborting wipe" Write-Host "FAILED: Backup could not be verified — profile NOT wiped" -ForegroundColor Red exit 1 } } } else { Add-Content $logPath "[STEP5] No existing profile — fresh install path" } } catch { $errMsg = $_.Exception.Message; Add-Content $logPath "[ERROR] Step5: $errMsg"; Write-Host "FAILED: $errMsg" -ForegroundColor Red; exit 1 } # ----------------------------------------------------------------------------- # STEP 6 — Download installer with retry + SHA256 verify # ----------------------------------------------------------------------------- $installerUrl = "https://mnemosynec.ai/download/MnemosyneC-Setup-0.5.0.exe" $installerPath = "$env:TEMP\MnemosyneC-Setup-0.5.0.exe" $expectedHash = "33765390E1E242817A24E4E0C80237E0C4CB3668BD6175631E80C7E231B9779E" try { if ($WhatIf) { Write-Host "What if: Invoke-WebRequest -Uri '$installerUrl' -OutFile '$installerPath'" } else { $downloaded = $false for ($attempt = 1; $attempt -le 3; $attempt++) { try { Add-Content $logPath "[STEP6] Download attempt $attempt of 3..." Invoke-WebRequest -Uri $installerUrl -OutFile $installerPath -UseBasicParsing -ErrorAction Stop $downloaded = $true Add-Content $logPath "[STEP6] Download succeeded on attempt $attempt" break } catch { Add-Content $logPath "[STEP6] Attempt $attempt failed: $($_.Exception.Message)" if ($attempt -lt 3) { Start-Sleep -Seconds 5 } } } if (-not $downloaded) { Add-Content $logPath "[ERROR] All 3 download attempts failed" Write-Host "FAILED: Could not download MnemosyneC installer after 3 attempts. Check your internet connection." -ForegroundColor Red exit 1 } # SHA256 verify $actualHash = (Get-FileHash $installerPath -Algorithm SHA256).Hash if ($skipHashCheck) { Add-Content $logPath "[STEP6] WARNING: Hash check skipped (skipHashCheck=true). Actual hash: $actualHash" } elseif ($actualHash -ne $expectedHash) { Add-Content $logPath "[ERROR] HASH MISMATCH — expected: $expectedHash, got: $actualHash" Write-Host "FAILED: Installer hash mismatch — aborting for security. Contact support." -ForegroundColor Red exit 1 } else { Add-Content $logPath "[STEP6] SHA256 verified OK: $actualHash" } } } catch { $errMsg = $_.Exception.Message; Add-Content $logPath "[ERROR] Step6: $errMsg"; Write-Host "FAILED: $errMsg" -ForegroundColor Red; exit 1 } # ----------------------------------------------------------------------------- # STEP 7 — Run installer silently # ----------------------------------------------------------------------------- try { if ($WhatIf) { Write-Host "What if: Start-Process -FilePath '$installerPath' -ArgumentList '/S' -Wait -NoNewWindow" } else { $proc = Start-Process -FilePath $installerPath -ArgumentList "/S" -Wait -NoNewWindow -PassThru $exitCode = $proc.ExitCode Add-Content $logPath "[STEP7] Installer completed with exit code: $exitCode" if ($exitCode -ne 0) { Write-Host "FAILED: Installer exited with code $exitCode" -ForegroundColor Red exit 1 } } } catch { $errMsg = $_.Exception.Message; Add-Content $logPath "[ERROR] Step7: $errMsg"; Write-Host "FAILED: $errMsg" -ForegroundColor Red; exit 1 } # ----------------------------------------------------------------------------- # STEP 8 — Launch MnemosyneC with 5-second delay # ----------------------------------------------------------------------------- try { Start-Sleep -Seconds 5 $installPaths = @( "$env:LOCALAPPDATA\Programs\mnemosynec\MnemosyneC.exe", "$env:PROGRAMFILES\MnemosyneC\MnemosyneC.exe", "${env:PROGRAMFILES(X86)}\MnemosyneC\MnemosyneC.exe" ) $exePath = $null foreach ($p in $installPaths) { if (Test-Path $p) { $exePath = $p; break } } if ($WhatIf) { if ($exePath) { Write-Host "What if: Start-Process -FilePath '$exePath'" } else { Write-Host "What if: Start-Process -FilePath ''" } Add-Content $logPath "[STEP8] WhatIf: would launch MnemosyneC from: $(if ($exePath) { $exePath } else { 'NOT FOUND' })" } else { if (-not $exePath) { Add-Content $logPath "[ERROR] MnemosyneC.exe not found after install — check install path" Write-Host "FAILED: MnemosyneC.exe not found after install. Check install path." -ForegroundColor Red exit 1 } Start-Process -FilePath $exePath Add-Content $logPath "[STEP8] MnemosyneC launched from: $exePath" } } catch { $errMsg = $_.Exception.Message; Add-Content $logPath "[ERROR] Step8: $errMsg"; Write-Host "FAILED: $errMsg" -ForegroundColor Red; exit 1 } # ----------------------------------------------------------------------------- # STEP 9 — Open mesh-test landing # ----------------------------------------------------------------------------- # PLACEHOLDER URL — easy to swap when Founder provides final URL $meshTestUrl = "https://mnemosynec.ai/welcome/mesh-test" try { if ($WhatIf) { Write-Host "What if: Start-Process '$meshTestUrl'" } else { Start-Process $meshTestUrl Add-Content $logPath "[STEP9] Opened mesh-test landing page: $meshTestUrl" } } catch { $errMsg = $_.Exception.Message; Add-Content $logPath "[ERROR] Step9: $errMsg"; Write-Host "FAILED: $errMsg" -ForegroundColor Red; exit 1 } # ----------------------------------------------------------------------------- # STEP 10 — Final success message # ----------------------------------------------------------------------------- try { $doneTime = Get-Date -Format "yyyy-MM-dd HH:mm:ss" Add-Content $logPath "[$doneTime] SonPatch completed successfully" Write-Host "" Write-Host "============================================" -ForegroundColor Green Write-Host " SonPatch complete!" -ForegroundColor Green Write-Host " MnemosyneC v0.5.0 is installed and open." -ForegroundColor Green Write-Host " Log saved to: $logPath" -ForegroundColor Green Write-Host "============================================" -ForegroundColor Green Write-Host "" Start-Sleep -Seconds 10 } catch { $errMsg = $_.Exception.Message; Add-Content $logPath "[ERROR] Step10: $errMsg"; Write-Host "FAILED: $errMsg" -ForegroundColor Red; exit 1 }