<# .SYNOPSIS Phase 6.2 exit-gate compliance check — stub. Each `Assert-*` either passes (Write-Host green) or throws. Non-zero exit = fail. .DESCRIPTION Validates Phase 6.2 (Authorization runtime) completion. Checks enumerated in `docs/v2/implementation/phase-6-2-authorization-runtime.md` §"Compliance Checks (run at exit gate)". Current status: SCAFFOLD. Every check writes a TODO line and does NOT throw. Each implementation task in Phase 6.2 is responsible for replacing its TODO with a real check before closing that task. .NOTES Usage: pwsh ./scripts/compliance/phase-6-2-compliance.ps1 Exit: 0 = all checks passed (or are still TODO); non-zero = explicit fail #> [CmdletBinding()] param() $ErrorActionPreference = 'Stop' $script:failures = 0 function Assert-Todo { param([string]$Check, [string]$ImplementationTask) Write-Host " [TODO] $Check (implement during $ImplementationTask)" -ForegroundColor Yellow } function Assert-Pass { param([string]$Check) Write-Host " [PASS] $Check" -ForegroundColor Green } function Assert-Fail { param([string]$Check, [string]$Reason) Write-Host " [FAIL] $Check — $Reason" -ForegroundColor Red $script:failures++ } Write-Host "" Write-Host "=== Phase 6.2 compliance — Authorization runtime ===" -ForegroundColor Cyan Write-Host "" Write-Host "Stream A — LdapGroupRoleMapping (control plane)" Assert-Todo "Control/data-plane separation — Core.Authorization has zero refs to LdapGroupRoleMapping" "Stream A.2" Assert-Todo "Authoring validation — AclsTab rejects duplicate (LdapGroup, Scope) pre-save" "Stream A.3" Write-Host "" Write-Host "Stream B — Evaluator + trie + cache" Assert-Todo "Trie invariants — PermissionTrieBuilder idempotent (build twice == equal)" "Stream B.1" Assert-Todo "Additive grants + cluster isolation — cross-cluster leakage impossible" "Stream B.1" Assert-Todo "Galaxy FolderSegment coverage — folder-subtree grant cascades; siblings unaffected" "Stream B.2" Assert-Todo "Redundancy-safe invalidation — generation-mismatch forces trie re-load on peer" "Stream B.4" Assert-Todo "Membership freshness — 15 min interval elapsed + LDAP down = fail-closed" "Stream B.5" Assert-Todo "Auth cache fail-closed — 5 min AuthCacheMaxStaleness exceeded = NotGranted" "Stream B.5" Assert-Todo "AuthorizationDecision shape — Allow + NotGranted only; Denied variant exists unused" "Stream B.6" Write-Host "" Write-Host "Stream C — OPC UA operation wiring" Assert-Todo "Every operation wired — Browse/Read/Write/HistoryRead/HistoryUpdate/CreateMonitoredItems/TransferSubscriptions/Call/Ack/Confirm/Shelve" "Stream C.1-C.7" Assert-Todo "HistoryRead uses its own flag — Read+no-HistoryRead denies HistoryRead" "Stream C.3" Assert-Todo "Mixed-batch semantics — 3 allowed + 2 denied returns per-item status, no coarse failure" "Stream C.6" Assert-Todo "Browse ancestor visibility — deep grant implies ancestor browse; denied ancestors filter" "Stream C.7" Assert-Todo "Subscription re-authorization — revoked grant surfaces BadUserAccessDenied in one publish" "Stream C.5" Write-Host "" Write-Host "Stream D — Admin UI + SignalR invalidation" Assert-Todo "SignalR invalidation — sp_PublishGeneration pushes PermissionTrieCache invalidate < 2 s" "Stream D.4" Write-Host "" Write-Host "Cross-cutting" Assert-Todo "No test-count regression — dotnet test ZB.MOM.WW.OtOpcUa.slnx count ≥ pre-Phase-6.2 baseline" "Final exit-gate" Write-Host "" if ($script:failures -eq 0) { Write-Host "Phase 6.2 compliance: scaffold-mode PASS (all checks TODO)" -ForegroundColor Green exit 0 } Write-Host "Phase 6.2 compliance: $script:failures FAIL(s)" -ForegroundColor Red exit 1