After shipping the four Phase 6 plan drafts (PRs 77-80), the adversarial-review
adjustments lived only as trailing "Review" sections. An implementer reading
Stream A would find the original unadjusted guidance, then have to cross-reference
the review to reconcile. This PR makes the plans genuinely executable:
1. Merges every ACCEPTed review finding into the actual Scope / Stream / Compliance
sections of each phase plan:
- phase-6-1: Scope table rewrite (per-capability retry, (instance,host) pipeline key,
MemoryTracking vs MemoryRecycle split, hybrid watchdog formula, demand-aware
wedge detector, generation-sealed LiteDB). Streams A/B/D + Compliance rewritten.
- phase-6-2: AuthorizationDecision tri-state, control/data-plane separation,
MembershipFreshnessInterval (15 min), AuthCacheMaxStaleness (5 min),
subscription stamp-and-reevaluate. Stream C widened to 11 OPC UA operations.
- phase-6-3: 8-state ServiceLevel matrix (OPC UA Part 5 §6.3.34-compliant),
two-layer peer probe (/healthz + UaHealthProbe), apply-lease via await using,
publish-generation fencing, InvalidTopology runtime state, ServerUriArray
self-first + peers. New Stream F (interop matrix + Galaxy failover).
- phase-6-4: DraftRevisionToken concurrency control, staged-import via
EquipmentImportBatch with user-scoped visibility, CSV header version marker,
decision-#117-aligned identifier columns, 1000-row diff cap,
decision-#139 OPC 40010 fields, Identification inherits Equipment ACL.
2. Appends decisions #143 through #162 to docs/v2/plan.md capturing the
architectural commitments the adjustments created. Each decision carries its
dated rationale so future readers know why the choice was made.
3. Scaffolds scripts/compliance/phase-6-{1,2,3,4}-compliance.ps1 — PowerShell
stubs with Assert-Todo / Assert-Pass / Assert-Fail helpers. Every check
maps to a Stream task ID from the corresponding phase plan. Currently all
checks are TODO and scripts exit 0; each implementation task is responsible
for replacing its TODO with a real check before closing that task. Saved
as UTF-8 with BOM so Windows PowerShell 5.1 parses em-dash characters
without breaking.
Net result: the Phase 6.1 plan is genuinely ready to execute. Stream A.3 can
start tomorrow without reconciling Streams vs. Review on every task; the
compliance script is wired to the Stream IDs; plan.md has the architectural
commitments that justify the Stream choices.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
82 lines
3.7 KiB
PowerShell
82 lines
3.7 KiB
PowerShell
<#
|
|
.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
|