$ErrorActionPreference = 'Stop' $root = Split-Path -Parent $PSScriptRoot function Read-RequiredFile([string]$relativePath) { $path = Join-Path $root $relativePath if (-not (Test-Path -LiteralPath $path -PathType Leaf)) { throw "AUTH-POST-COMMIT-NAVIGATION-CONTRACT BLOCKED`n- missing file: $relativePath" } return Get-Content -LiteralPath $path -Raw -Encoding UTF8 } $issues = [System.Collections.Generic.List[string]]::new() $a01 = Read-RequiredFile 'pages/auth/a01-entry.vue' $a04 = Read-RequiredFile 'pages/auth/a04-register.vue' $pages = Read-RequiredFile 'pages.json' function Require-Text( [string]$content, [string]$expected, [string]$message ) { if (-not $content.Contains($expected)) { $script:issues.Add($message) } } function Require-Pattern( [string]$content, [string]$pattern, [string]$message ) { if ($content -notmatch $pattern) { $script:issues.Add($message) } } Require-Text -content $a01 -expected 'const authenticationCommitted = ref(false);' -message 'A01 must remember that remote authentication already committed' Require-Text -content $a01 -expected 'const enterAuthenticatedRoot = async () =>' -message 'A01 must own a navigation-only retry after authentication commits' Require-Text -content $a01 -expected 'authenticationCommitted.value = true;' -message 'A01 must mark the remote authentication result before navigation' Require-Text -content $a01 -expected 'const authenticationNavigationFailure =' -message 'A01 must own a navigation-specific failure message' Require-Pattern -content $a01 -pattern '(?s)if \(authenticationCommitted\.value\)\s*return enterAuthenticatedRoot\(\);' -message 'A01 repeated submit after commit must retry only the local navigation' Require-Text -content $a01 -expected 'const opened = await goRoot("G01");' -message 'A01 must inspect the navigation gateway boolean result' Require-Text -content $a01 -expected 'if (opened !== true)' -message 'A01 must treat a false navigation result as retryable failure' Require-Text -content $a04 -expected 'const registrationCommitted = ref(false);' -message 'A04 must remember that the remote registration already committed' Require-Text -content $a04 -expected 'const enterAuthenticatedRoot = async () =>' -message 'A04 must own a navigation-only retry after registration commits' Require-Text -content $a04 -expected 'registrationCommitted.value = true;' -message 'A04 must mark the remote registration result before navigation' Require-Text -content $a04 -expected 'const registrationNavigationFailure =' -message 'A04 must own a navigation-specific failure message' Require-Pattern -content $a04 -pattern '(?s)if \(registrationCommitted\.value\)\s*return enterAuthenticatedRoot\(\);' -message 'A04 repeated submit after commit must retry only the local navigation' Require-Pattern -content $a04 -pattern '(?s)await appApi\.registerWithPassword\([\s\S]*?registrationCommitted\.value = true;\s*\}\s*catch' -message 'A04 must establish the registration commit before leaving the remote-write catch' Require-Pattern -content $a04 -pattern '(?s)\}\s*catch \(error\) \{[\s\S]*?\}\s*finally[\s\S]*?\}\s*if \(!pageActive\) return;\s*await enterAuthenticatedRoot\(\);' -message 'A04 navigation must execute after the registration failure boundary' Require-Text -content $a04 -expected 'const opened = await goRoot("G01");' -message 'A04 must inspect the navigation gateway boolean result' Require-Text -content $a04 -expected 'if (opened !== true)' -message 'A04 must treat a false navigation result as retryable failure' Require-Pattern -content $a04 -pattern '(?s)const requestBack = \(\) =>\s*registrationCommitted\.value\s*\?\s*enterAuthenticatedRoot\(\)' -message 'A04 committed registration must not enter the unsaved discard flow' Require-Pattern -content $pages -pattern '"navigationBarTextStyle"\s*:\s*"white"' -message 'custom red headers require light Android status-bar content' if ($issues.Count -gt 0) { $lines = [System.Collections.Generic.List[string]]::new() $lines.Add('AUTH-POST-COMMIT-NAVIGATION-CONTRACT BLOCKED') foreach ($issue in $issues) { $lines.Add("- $issue") } throw ($lines -join [Environment]::NewLine) } Write-Output 'AUTH-POST-COMMIT-NAVIGATION-CONTRACT PASS'