diff --git a/.github/workflows/interoperability-reference-guard.yml b/.github/workflows/interoperability-reference-guard.yml index 8922b09d7..709c3f377 100644 --- a/.github/workflows/interoperability-reference-guard.yml +++ b/.github/workflows/interoperability-reference-guard.yml @@ -84,6 +84,8 @@ jobs: -not [bool]$association.physicalAcceptance.actualInformationReportObserved) { throw 'Accepted post-baseline SCL association authority drifted or lost physical evidence.' } + . .\ARSAS\scripts\test-p10-9f-core-routing-trial.ps1 + $coreRoutingTrialValid = Test-P109FCoreRoutingTrial -Lock $lock $trial = $lock.smartInteroperabilityCodeTrial $serverAt = $lock.sclServerAtTrial $originalTrial = $lock.commit -eq $trial.exactCommit -and @@ -131,7 +133,7 @@ jobs: if ($trial.status -ne 'code-verified-not-physical' -or [int]$trial.issue -ne 144 -or [int]$trial.integrationPullRequest -ne 148 -or - -not ($originalTrial -or $serverAtTrial -or $datasetTrial -or $p10Trial) -or + -not ($originalTrial -or $serverAtTrial -or $datasetTrial -or $p10Trial -or $coreRoutingTrialValid) -or -not [bool]$trial.fullDiscoveryFallbackForbidden -or -not [bool]$trial.vendorBranchingForbidden -or -not [bool]$trial.physicalPromotionRequired) { diff --git a/.github/workflows/scl-interoperability-r7.yml b/.github/workflows/scl-interoperability-r7.yml index aa5faf586..9b69feac8 100644 --- a/.github/workflows/scl-interoperability-r7.yml +++ b/.github/workflows/scl-interoperability-r7.yml @@ -81,6 +81,8 @@ jobs: throw 'Physical SCL-association/R10 provenance is not intact.' } + . .\ARSAS\scripts\test-p10-9f-core-routing-trial.ps1 + $coreRoutingTrialValid = Test-P109FCoreRoutingTrial -Lock $lock $trial = $lock.smartInteroperabilityCodeTrial if ($null -ne $trial -and $lock.commit -eq $trial.exactCommit) { if ([int]$lock.sourcePullRequest -ne 148 -or @@ -146,6 +148,9 @@ jobs: } Write-Host 'P10 trusted-SCL identity trial accepted for code CI ONLY; R7/R10 physical gate unchanged.' } + elseif ($coreRoutingTrialValid) { + Write-Host 'P10.9F routing core accepted for CodeVerified staging CI ONLY; R7/R10 physical authority unchanged.' + } elseif ($lock.commit -eq $convergence.activeStack.engineModelAndScl.head) { if ([int]$lock.sourcePullRequest -notin @(134, 135) -or $lock.purpose -notmatch 'R7 physical SCL repair pin') { diff --git a/.github/workflows/smart-discovery-mainline-readiness.yml b/.github/workflows/smart-discovery-mainline-readiness.yml index 22655d396..f5735b4a4 100644 --- a/.github/workflows/smart-discovery-mainline-readiness.yml +++ b/.github/workflows/smart-discovery-mainline-readiness.yml @@ -109,6 +109,8 @@ jobs: # P10.1: exact, bounded and ancestry-checked code-trial allowlist. # This never grants field acceptance or mainline promotion. + . .\scripts\test-p10-9f-core-routing-trial.ps1 + $coreRoutingTrialValid = Test-P109FCoreRoutingTrial -Lock $lock $trial = $lock.smartInteroperabilityCodeTrial $serverAt = $lock.sclServerAtTrial $closure = $lock.datasetFirstDiscoveryTrial @@ -160,7 +162,7 @@ jobs: $lock.commit -eq $p10.exactCommit -and [int]$lock.sourcePullRequest -eq 161 - if ($originalTrial -or $serverAtTrial -or $datasetTrial -or $p10Trial) { + if ($originalTrial -or $serverAtTrial -or $datasetTrial -or $p10Trial -or $coreRoutingTrialValid) { if (-not $historicalTrialValid -or $lock.ref -ne 'main') { throw 'Stacked trial identity or ancestor authority is inconsistent.' diff --git a/engines/ARIEC61850.lock.json b/engines/ARIEC61850.lock.json index 7ff7d95c0..5c67895cc 100644 --- a/engines/ARIEC61850.lock.json +++ b/engines/ARIEC61850.lock.json @@ -2,9 +2,9 @@ "schemaVersion": 1, "repository": "masarray/ARIEC61850", "ref": "main", - "commit": "00ad2819b99ffe6b3f885e59aa24a6afb2b4d8e1", - "sourcePullRequest": 161, - "purpose": "P10 VERIFIED-SCL IDENTITY CODE TRIAL on exact PR #157 dataset-first Discovery baseline. Includes canonical live Save SCL propagation with original accepted association evidence and LD instance values, after PR #161 correction commit; physical BCUGE test pending. No change to existing MMS report/control/cyclic scheduler.", + "commit": "fa93c9fdc7cd98fd3624227ee21c3eefc68bcac7", + "sourcePullRequest": 164, + "purpose": "P10.9E client MMS report-routing integrity lock: quarantine contradictory full DatSet/RptID before value projection (PR #164). Also includes P10.9D simulator-only FIFO emission and CI staging PR trigger (PR #163). Previous BCUGE static acquisition remains authority: zero cyclic polling and unchanged decoder, GI, controls and report activation. The simulator FIFO fix is not ARSAS client runtime and does not establish real BCUGE SOE continuity.", "previousTrialPin": { "commit": "4467124775d8d9d76f3db194f9fbfd97144767a8", "sourcePullRequest": 134, @@ -84,6 +84,21 @@ "cyclicMmsProcessPollingForbidden": true, "physicalQualificationRequired": true }, + "coreReportRoutingTrial": { + "status": "code-verified-not-physical", + "issue": 531, + "simulatorPullRequest": 163, + "corePullRequest": 164, + "baseEngineCommit": "00ad2819b99ffe6b3f885e59aa24a6afb2b4d8e1", + "simulatorFifoCommit": "ef0fe44f3b40e47dc18b1aac4476b635e67d531e", + "exactCommit": "fa93c9fdc7cd98fd3624227ee21c3eefc68bcac7", + "simulatorCiRun": 38141582981, + "coreCiRun": 38142115574, + "physicalQualificationRequired": true, + "mainlinePromotionForbidden": true, + "fullDiscoveryFallbackForbidden": true, + "cyclicMmsProcessPollingForbidden": true + }, "p10IdentityTrial": { "status": "code-trial-not-physical", "enginePullRequest": 161, diff --git a/scripts/resolve-ariec-lock.ps1 b/scripts/resolve-ariec-lock.ps1 index ad525f606..00f4172c4 100644 --- a/scripts/resolve-ariec-lock.ps1 +++ b/scripts/resolve-ariec-lock.ps1 @@ -117,11 +117,14 @@ if ($null -ne $lock.sclAssociationInteroperability) { [bool]$p10.fullNameListFallbackForbidden -and [bool]$p10.cyclicMmsProcessPollingForbidden + . (Join-Path $PSScriptRoot 'test-p10-9f-core-routing-trial.ps1') + $coreRoutingTrialValid = Test-P109FCoreRoutingTrial -Lock $lock $acceptedTrial = ( ($trialValid -and [string]$lock.commit -ceq [string]$trial.exactCommit -and [int]$lock.sourcePullRequest -eq 148) -or ($serverAtValid -and [string]$lock.commit -ceq [string]$serverAt.exactCommit -and [int]$lock.sourcePullRequest -eq 153) -or ($closureValid -and [string]$lock.commit -ceq [string]$closure.exactCommit -and [int]$lock.sourcePullRequest -eq 157) -or - ($p10Valid -and [string]$lock.commit -ceq [string]$p10.exactCommit -and [int]$lock.sourcePullRequest -eq 161) + ($p10Valid -and [string]$lock.commit -ceq [string]$p10.exactCommit -and [int]$lock.sourcePullRequest -eq 161) -or + ($p10Valid -and $coreRoutingTrialValid) ) if (-not $historicalAnchorValid -or -not $acceptedTrial) { throw 'SCL association physical-tested engine head differs from integration lock.' diff --git a/scripts/test-p10-9f-core-routing-trial.ps1 b/scripts/test-p10-9f-core-routing-trial.ps1 new file mode 100644 index 000000000..7827aa251 --- /dev/null +++ b/scripts/test-p10-9f-core-routing-trial.ps1 @@ -0,0 +1,64 @@ +# PowerShell 5.1/7 compatible. Code-verification does NOT grant physical acceptance. +# Exactly one audited core routing candidate; no wildcard SHA, no runtime overrides. +function Test-P109FCoreRoutingTrial { + param([Parameter(Mandatory = $true)] [object] $Lock) + $candidate = $Lock.coreReportRoutingTrial + if ([string]$Lock.commit -cne 'fa93c9fdc7cd98fd3624227ee21c3eefc68bcac7' -or + [int]$Lock.sourcePullRequest -ne 164 -or + [string]$Lock.repository -cne 'masarray/ARIEC61850' -or + [string]$Lock.ref -cne 'main' -or $null -eq $candidate) { return $false } + + # A code-only candidate cannot be interpreted as physical authority, + # including CI builds targeting or running on main. + foreach ($ref in @($env:PR_BASE_REF, $env:SOURCE_REF_NAME, + $env:GITHUB_BASE_REF, $env:GITHUB_REF_NAME)) { + if ([string]$ref -ceq 'main' -or [string]$ref -ceq 'refs/heads/main') { + return $false + } + } + $p10 = $Lock.p10IdentityTrial + $closure = $Lock.datasetFirstDiscoveryTrial + $association = $Lock.sclAssociationInteroperability + $historical = $Lock.smartInteroperabilityCodeTrial + $serverAt = $Lock.sclServerAtTrial + if ($null -eq $p10 -or $null -eq $closure -or $null -eq $association -or + $null -eq $historical -or $null -eq $serverAt) { return $false } + + return ( + [string]$candidate.status -ceq 'code-verified-not-physical' -and + [int]$candidate.issue -eq 531 -and + [int]$candidate.simulatorPullRequest -eq 163 -and + [int]$candidate.corePullRequest -eq 164 -and + [string]$candidate.baseEngineCommit -ceq '00ad2819b99ffe6b3f885e59aa24a6afb2b4d8e1' -and + [string]$candidate.simulatorFifoCommit -ceq 'ef0fe44f3b40e47dc18b1aac4476b635e67d531e' -and + [string]$candidate.exactCommit -ceq 'fa93c9fdc7cd98fd3624227ee21c3eefc68bcac7' -and + [long]$candidate.simulatorCiRun -eq 38141582981 -and + [long]$candidate.coreCiRun -eq 38142115574 -and + [bool]$candidate.physicalQualificationRequired -and + [bool]$candidate.mainlinePromotionForbidden -and + [bool]$candidate.fullDiscoveryFallbackForbidden -and + [bool]$candidate.cyclicMmsProcessPollingForbidden -and + [string]$p10.exactCommit -ceq [string]$candidate.baseEngineCommit -and + [string]$p10.exactCommit -ceq '00ad2819b99ffe6b3f885e59aa24a6afb2b4d8e1' -and + [int]$p10.enginePullRequest -eq 161 -and + [string]$p10.baseEngineCommit -ceq [string]$closure.exactCommit -and + [string]$p10.identitySource -ceq 'TrustedSclExactDomainMatch' -and + [string]$p10.status -ceq 'code-trial-not-physical' -and + [bool]$p10.physicalQualificationRequired -and + [bool]$p10.fullNameListFallbackForbidden -and + [bool]$p10.cyclicMmsProcessPollingForbidden -and + [string]$closure.exactCommit -ceq '8b0c0f7e695b016834e40a6f068994dcc945cb1a' -and + [string]$closure.baseEngineCommit -ceq [string]$serverAt.exactCommit -and + [string]$serverAt.exactCommit -ceq '352c81e6a798635c6addcee0683235ca87ad416d' -and + [string]$serverAt.baseEngineCommit -ceq [string]$historical.exactCommit -and + [string]$historical.exactCommit -ceq '9c5292570f55dd81be1b3a6b56f937e5ba1ed276' -and + [string]$association.testedEngineCommit -ceq '84e9820e5a32690475960e49d5ef74e6637847fd' -and + [string]$association.mergedEngineCommit -ceq 'e5deed1d8aa11d97991695c6e390baafea7ab797' -and + [string]$association.contractId -ceq 'SCL-ASSOC-PARTIAL-ADDR-PHYSICAL' -and + [bool]$association.preservesR10DiscoveryModelBaseline -and + [bool]$association.fullDiscoveryFallbackForbidden -and + [bool]$association.cyclicMmsProcessPollingForbidden -and + [string]$Lock.mergedMainCommit -ceq '648124097621046f5f127ceb1cf853fea54db730' -and + [string]$Lock.previousStablePin.commit -ceq [string]$Lock.mergedMainCommit + ) +} diff --git a/tests/ARSAS.Tests/CanonicalLiveSclExportRegressionTests.cs b/tests/ARSAS.Tests/CanonicalLiveSclExportRegressionTests.cs index d1a5e739d..4756cc748 100644 --- a/tests/ARSAS.Tests/CanonicalLiveSclExportRegressionTests.cs +++ b/tests/ARSAS.Tests/CanonicalLiveSclExportRegressionTests.cs @@ -420,9 +420,13 @@ public void EngineLock_PreservesPhysicalSclRepairBaselineAcrossCodeVerifiedInter var p10 = root.GetProperty("p10IdentityTrial"); Assert.Equal(closure.GetProperty("exactCommit").GetString(), p10.GetProperty("baseEngineCommit").GetString()); + Assert.Equal("00ad2819b99ffe6b3f885e59aa24a6afb2b4d8e1", p10.GetProperty("exactCommit").GetString()); + var coreTrial = root.GetProperty("coreReportRoutingTrial"); Assert.Equal(p10.GetProperty("exactCommit").GetString(), + coreTrial.GetProperty("baseEngineCommit").GetString()); + Assert.Equal(coreTrial.GetProperty("exactCommit").GetString(), root.GetProperty("commit").GetString()); - Assert.Equal(161, root.GetProperty("sourcePullRequest").GetInt32()); + Assert.Equal(164, root.GetProperty("sourcePullRequest").GetInt32()); Assert.Equal("code-trial-not-physical",p10.GetProperty("status").GetString()); Assert.True(p10.GetProperty("physicalQualificationRequired").GetBoolean()); Assert.True(closure.GetProperty("physicalQualificationRequired").GetBoolean()); diff --git a/tests/ARSAS.Tests/P10MainlinePolicyExecutionTests.cs b/tests/ARSAS.Tests/P10MainlinePolicyExecutionTests.cs index 85b956267..8f2ef8779 100644 --- a/tests/ARSAS.Tests/P10MainlinePolicyExecutionTests.cs +++ b/tests/ARSAS.Tests/P10MainlinePolicyExecutionTests.cs @@ -11,6 +11,10 @@ public sealed class P10MainlinePolicyExecutionTests { [Theory] [InlineData("p10-stacked-valid", true)] + [InlineData("core-trial-wrong-exact-sha-denied", false)] + [InlineData("core-trial-wrong-base-denied", false)] + [InlineData("core-trial-wrong-ci-denied", false)] + [InlineData("core-trial-physical-flag-denied", false)] [InlineData("p10-pr-main-denied", false)] [InlineData("p10-source-main-denied", false)] [InlineData("p10-wrong-sha-denied", false)] @@ -51,6 +55,9 @@ public void Exact_CI_Gate_Fails_Closed_Without_False_Physical_Promotion( { Directory.CreateDirectory(Path.Combine(folder, "engines")); Directory.CreateDirectory(Path.Combine(folder, "evidence")); + Directory.CreateDirectory(Path.Combine(folder, "scripts")); + File.Copy(Path.Combine(root, "scripts", "test-p10-9f-core-routing-trial.ps1"), + Path.Combine(folder, "scripts", "test-p10-9f-core-routing-trial.ps1")); var lockDoc = JsonNode.Parse(File.ReadAllText(Path.Combine(root, "engines", "ARIEC61850.lock.json")))!.AsObject(); @@ -59,6 +66,14 @@ public void Exact_CI_Gate_Fails_Closed_Without_False_Physical_Promotion( switch (scenario) { case "p10-pr-main-denied": baseRef = "main"; break; + case "core-trial-wrong-exact-sha-denied": + lockDoc["coreReportRoutingTrial"]!["exactCommit"] = new string('0', 40); break; + case "core-trial-wrong-base-denied": + lockDoc["coreReportRoutingTrial"]!["baseEngineCommit"] = new string('0', 40); break; + case "core-trial-wrong-ci-denied": + lockDoc["coreReportRoutingTrial"]!["coreCiRun"] = 0; break; + case "core-trial-physical-flag-denied": + lockDoc["coreReportRoutingTrial"]!["physicalQualificationRequired"] = false; break; case "p10-source-main-denied": sourceRef = "main"; break; case "p10-wrong-sha-denied": lockDoc["p10IdentityTrial"]!["exactCommit"] = new string('0', 40); break; diff --git a/tests/ARSAS.Tests/SmartInteroperabilityTrialGuardRegressionTests.cs b/tests/ARSAS.Tests/SmartInteroperabilityTrialGuardRegressionTests.cs index c3e996a84..5cbe62eb9 100644 --- a/tests/ARSAS.Tests/SmartInteroperabilityTrialGuardRegressionTests.cs +++ b/tests/ARSAS.Tests/SmartInteroperabilityTrialGuardRegressionTests.cs @@ -70,9 +70,15 @@ public void TrialLock_PreservesHistoricalPhysicalAuthorityAndExplicitlyRequiresP var p10 = root.GetProperty("p10IdentityTrial"); Assert.Equal(closure.GetProperty("exactCommit").GetString(), p10.GetProperty("baseEngineCommit").GetString()); + var codeTrial = root.GetProperty("coreReportRoutingTrial"); + Assert.Equal(p10.GetProperty("exactCommit").GetString(), + codeTrial.GetProperty("baseEngineCommit").GetString()); Assert.Equal(root.GetProperty("commit").GetString(), - p10.GetProperty("exactCommit").GetString()); - Assert.Equal(161,root.GetProperty("sourcePullRequest").GetInt32()); + codeTrial.GetProperty("exactCommit").GetString()); + Assert.Equal("code-verified-not-physical", codeTrial.GetProperty("status").GetString()); + Assert.True(codeTrial.GetProperty("physicalQualificationRequired").GetBoolean()); + Assert.True(codeTrial.GetProperty("mainlinePromotionForbidden").GetBoolean()); + Assert.Equal(164,root.GetProperty("sourcePullRequest").GetInt32()); Assert.Equal("code-trial-not-physical",p10.GetProperty("status").GetString()); Assert.True(p10.GetProperty("physicalQualificationRequired").GetBoolean()); Assert.True(p10.GetProperty("cyclicMmsProcessPollingForbidden").GetBoolean());