Skip to content

M2.17-M P0: reconcile #618/#620; canonical Data Model focused hydration + Explorer read SSOT #1310

M2.17-M P0: reconcile #618/#620; canonical Data Model focused hydration + Explorer read SSOT

M2.17-M P0: reconcile #618/#620; canonical Data Model focused hydration + Explorer read SSOT #1310

name: Smart Discovery Production Promotion Guard
on:
pull_request:
paths:
- "*.cs"
- "**/*.cs"
- "*.csproj"
- "**/*.csproj"
- "*.sln"
- "**/*.sln"
- "*.props"
- "**/*.props"
- "*.targets"
- "**/*.targets"
- "global.json"
- "*.xaml"
- "**/*.xaml"
- "app.manifest"
- "VERSION"
- ".release/**"
- ".github/workflows/**"
- "Assets/**"
- "Resources/**"
- "installer/**"
- "engine-patches/**"
- "landing/release-notes*.json"
- "landing/latest.json"
- "engines/**"
- "scripts/**"
- "tests/**"
- "evidence/**"
- "docs/INTEROPERABILITY_REFERENCE_CONTRACT.md"
- ".github/workflows/smart-discovery-*.yml"
workflow_dispatch:
permissions:
contents: read
actions: read
concurrency:
group: smart-discovery-production-promotion-${{ github.event_name == 'pull_request' && github.event.pull_request.number || github.run_id }}
cancel-in-progress: true
jobs:
verify-production-route:
name: Verify physical-proven Smart Discovery production parity
runs-on: windows-latest
timeout-minutes: 25
steps:
- name: Checkout exact ARSAS candidate
uses: actions/checkout@v7
with:
path: ArIED61850Tester
fetch-depth: 1
persist-credentials: false
- name: Verify exact tested ARSAS candidate SHA
shell: pwsh
env:
EXPECTED_SOURCE_SHA: ${{ github.sha }}
run: |
$actual = (git -C .\ArIED61850Tester rev-parse HEAD).Trim().ToLowerInvariant()
if ($actual -cne $env:EXPECTED_SOURCE_SHA) {
throw "Smart Discovery route guard checkout mismatch. Expected $env:EXPECTED_SOURCE_SHA, got $actual."
}
- name: Setup Python for bounded canonical evidence verification
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Run offline canonical-proof fail-closed fixtures
run: python .\ArIED61850Tester\scripts\test-ci-canonical-reuse.py
- id: engine
name: Resolve exact pinned ARIEC61850 integration authority
uses: ./ArIED61850Tester/.github/actions/resolve-ariec-engine
with:
lock-path: ArIED61850Tester/engines/ARIEC61850.lock.json
- name: Verify tracked production route and preserve source hash
shell: powershell
run: |
$native = '.\ArIED61850Tester\Services\NativeIec61850Client.cs'
$before = (Get-FileHash $native -Algorithm SHA256).Hash
"SMART_ROUTE_SOURCE_SHA256=$before" | Out-File $env:GITHUB_ENV -Encoding utf8 -Append
& .\ArIED61850Tester\scripts\enable-smart-discovery-capture.ps1 -VerifyOnly
if ($LASTEXITCODE -ne 0) { throw 'Smart Discovery route verification failed.' }
$after = (Get-FileHash $native -Algorithm SHA256).Hash
if ($after -ne $before) {
throw 'Verification mutated NativeIec61850Client.cs; build-time source mutation is forbidden.'
}
$source = Get-Content $native -Raw
foreach ($required in @(
'return await DiscoverSignalsSmartForCaptureAsync(cancellationToken, progress).ConfigureAwait(false);',
'__P0_5C_CONNECT_RESET__',
'__P0_5C_DISPOSE_RESET__',
'_lastDiscovery.Snapshot.DomainVariables')) {
if ($source -notmatch [regex]::Escape($required)) {
throw "Production Smart Discovery contract missing: $required"
}
}
- name: Require matching canonical Build ARSAS full regression evidence
if: github.event_name == 'pull_request'
shell: pwsh
env:
GITHUB_TOKEN: ${{ github.token }}
PR_HEAD_BRANCH: ${{ github.event.pull_request.head.ref }}
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
PR_MERGE_SHA: ${{ github.sha }}
PINNED_ENGINE_SHA: ${{ steps.engine.outputs.commit }}
run: |
python .\ArIED61850Tester\scripts\verify-ci-canonical-reuse.py `
--repository $env:GITHUB_REPOSITORY `
--head-branch $env:PR_HEAD_BRANCH `
--head-sha $env:PR_HEAD_SHA `
--merge-sha $env:PR_MERGE_SHA `
--engine-sha $env:PINNED_ENGINE_SHA `
--wait-seconds 960 `
--allow-in-progress-artifact `
--output (Join-Path $env:RUNNER_TEMP 'ci-production-route-canonical-proof.json')
if ($LASTEXITCODE -ne 0) {
throw 'Production route guard requires matching exact-SHA canonical full-regression PASS.'
}
- name: Summarize exact-source canonical regression parity
if: github.event_name == 'pull_request'
shell: pwsh
run: |
$proof = Get-Content (Join-Path $env:RUNNER_TEMP 'ci-production-route-canonical-proof.json') -Raw | ConvertFrom-Json
if ([int]$proof.failed -ne 0 -or [int]$proof.notExecuted -ne 0 -or
[int]$proof.passed -lt 1 -or
$proof.engineSha -ne '${{ steps.engine.outputs.commit }}') {
throw 'Production-route canonical full-regression proof is incomplete.'
}
@(
'## Smart Discovery production route — canonical full-regression reuse',
'',
"- exact PR merge SHA: $($proof.mergeSha)",
"- exact pinned engine SHA: $($proof.engineSha)",
"- canonical Build ARSAS run: $($proof.canonicalRunId)",
"- full regression: $($proof.passed) passed, $($proof.failed) failed",
"- canonical proof stage: $($proof.proofStage)",
"- canonical workflow completed: $($proof.workflowCompleted)",
"- packaging/smoke proven by this guard: $($proof.packagingSmokeProven)",
'- Build ARSAS remains the independent packaging/smoke check',
'- Production route source verified independently without any mutation',
'- No promotion or release action was performed'
) | Out-File $env:GITHUB_STEP_SUMMARY -Encoding utf8 -Append
- name: Prove canonical route remains immutable after evidence verification
shell: powershell
run: |
$native = '.\ArIED61850Tester\Services\NativeIec61850Client.cs'
$actualHash = (Get-FileHash $native -Algorithm SHA256).Hash
if ($actualHash -cne $env:SMART_ROUTE_SOURCE_SHA256) {
throw 'Route source changed during canonical evidence verification.'
}
& .\ArIED61850Tester\scripts\enable-smart-discovery-capture.ps1 -VerifyOnly
if ($LASTEXITCODE -ne 0) { throw 'Post-proof Smart Discovery route verification failed.' }
$finalHash = (Get-FileHash $native -Algorithm SHA256).Hash
if ($finalHash -cne $env:SMART_ROUTE_SOURCE_SHA256) {
throw 'Route verifier mutated production source.'
}
$targets = Get-Content '.\ArIED61850Tester\Directory.Build.targets' -Raw
if ($targets -match 'GITHUB_WORKFLOW' -or $targets -match 'SmartDiscoveryProductionPromoted') {
throw 'Discovery runtime still depends on workflow name or promotion switch.'
}
Write-Host 'Same tracked Smart Discovery route verified; exact-SHA canonical Build ARSAS supplies full regression proof.'
manual-regression:
name: Manual exact-SHA full production-route regression
if: github.event_name == 'workflow_dispatch'
uses: ./.github/workflows/_ci-p1-windows-build-test.yml
with:
source_sha: ${{ github.sha }}
shadow_mode: true
secrets: {}