Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
1fd30e5
refactor(evidence): use neutral reference schema while preserving num…
masarray Sep 24, 2026
30da491
refactor(evidence): retire vendor-named active reference path
masarray Sep 24, 2026
8ab5dec
docs(interoperability): neutralize active contract and preserve origi…
masarray Sep 24, 2026
520e587
docs(interoperability): retire external-product named document
masarray Sep 24, 2026
b500cba
refactor(ci): provide neutral IEC 61850 reference acceptance workflow
masarray Sep 24, 2026
27398d3
refactor(ci): retire external-product named workflow entrypoint
masarray Sep 24, 2026
b264502
refactor(ci): consume neutral interoperability reference evidence
masarray Sep 24, 2026
66f27a7
refactor(ci): consume neutral interoperability reference evidence
masarray Sep 24, 2026
07b4293
refactor(ci): consume neutral interoperability reference evidence
masarray Sep 24, 2026
4cf0a96
test(interoperability): assert neutral reference contract and unchang…
masarray Sep 24, 2026
bc93994
chore(provenance): remove retired name exceptions and neutralize synt…
masarray Sep 24, 2026
6b7c608
chore(provenance): remove retired name exceptions and neutralize synt…
masarray Sep 24, 2026
29963a9
test(interoperability): lock neutral schema to original physical proo…
masarray Sep 24, 2026
3796d46
test(provenance): align neutral contract checks with actual R10 schem…
masarray Sep 24, 2026
d769fdb
test(provenance): align neutral contract checks with actual R10 schem…
masarray Sep 24, 2026
d607668
fix(source-clean): scan every tracked file with no whole-file identif…
masarray Sep 24, 2026
22f2919
test(source-clean): exercise forbidden identifier rejection across al…
masarray Sep 24, 2026
319e213
test(ci): run end-to-end source-clean negative fixtures on every Wind…
masarray Sep 24, 2026
df32669
test(source-clean): assert whole-file exceptions are removed and nega…
masarray Sep 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ jobs:
shell: powershell
run: .\ArIED61850Tester\scripts\verify-source-clean.ps1

- name: Verify source-clean rejection fixtures
shell: powershell
run: .\ArIED61850Tester\scripts\test-source-clean-guard.ps1

- name: Verify premium UX, GOOSE, SMV, SAS and release invariants
shell: powershell
run: |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: IEDScout Convergence Guard
name: IEC 61850 Interoperability Reference Guard

on:
pull_request:
Expand All @@ -10,20 +10,20 @@ on:
- "Directory.Build.targets"
- "scripts/enable-smart-discovery-capture.ps1"
- "engines/ARIEC61850.lock.json"
- "evidence/iedscout-convergence-target.json"
- "docs/IEDSCOUT_CONVERGENCE.md"
- "evidence/interoperability-reference-target.json"
- "docs/INTEROPERABILITY_REFERENCE_CONTRACT.md"
- "tests/ARSAS.Tests/CanonicalLiveSclExportRegressionTests.cs"
- ".github/workflows/iedscout-convergence-guard.yml"
- ".github/workflows/interoperability-reference-guard.yml"
- ".github/workflows/scl-interoperability-r7.yml"
workflow_dispatch:

concurrency:
group: iedscout-convergence-${{ github.event.pull_request.number || github.ref }}
group: interoperability-reference-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
iedscout-convergence-contract:
name: iedscout-convergence-contract
interoperability-reference-contract:
name: interoperability-reference-contract
runs-on: windows-latest

steps:
Expand All @@ -47,7 +47,7 @@ jobs:
shell: pwsh
run: |
$lock = Get-Content .\ARSAS\engines\ARIEC61850.lock.json -Raw | ConvertFrom-Json
$target = Get-Content .\ARSAS\evidence\iedscout-convergence-target.json -Raw | ConvertFrom-Json
$target = Get-Content .\ARSAS\evidence\interoperability-reference-target.json -Raw | ConvertFrom-Json

if ($target.status -ne 'physical-retest-passed-merge-ready') {
throw "Convergence status changed unexpectedly: $($target.status)"
Expand All @@ -69,11 +69,11 @@ jobs:
-not [bool]$target.promotion.physicalRetestPassed) {
throw 'R10 physical-retest/merge gate drifted.'
}
if ([int]$target.physicalReference.iedScoutCapture.associations -ne 1 -or
[int]$target.physicalReference.iedScoutCapture.getVariableAccessAttributes -ne 119 -or
if ([int]$target.physicalReference.externalReferenceCapture.associations -ne 1 -or
[int]$target.physicalReference.externalReferenceCapture.getVariableAccessAttributes -ne 119 -or
[int]$target.physicalReference.rejectedLegacyArsasCapture.associations -ne 2 -or
[int]$target.physicalReference.rejectedLegacyArsasCapture.getVariableAccessAttributes -lt 20000) {
throw 'Physical IEDScout/legacy regression reference changed unexpectedly.'
throw 'Physical external IEC 61850 reference/legacy regression reference changed unexpectedly.'
}


Expand Down Expand Up @@ -306,7 +306,7 @@ jobs:
$singleFlight -notmatch 'DiscoverSmartSingleFlightAsync' -or
$singleFlight -notmatch 'DiscoverSmartAsync\(options, CancellationToken\.None\)' -or
$smartGva -notmatch 'GetVariableAccessAttributesSmartAsync') {
throw 'P0 structural discovery freeze regressed away from the accepted IEDScout convergence path.'
throw 'P0 structural discovery freeze regressed away from the accepted external IEC 61850 reference convergence path.'
}

if ($lnParts -notmatch 'instanceStart' -or
Expand All @@ -324,4 +324,4 @@ jobs:
throw 'Canonical IEC model / SCL semantic authority regressed.'
}

Write-Host 'IEDScout convergence contract PASS.'
Write-Host 'external IEC 61850 reference convergence contract PASS.'
22 changes: 11 additions & 11 deletions .github/workflows/scl-interoperability-r7.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ on:
- "MainWindow.xaml.cs"
- "Services/CanonicalSclReloadValidator.cs"
- "engines/ARIEC61850.lock.json"
- "evidence/iedscout-convergence-target.json"
- "docs/IEDSCOUT_CONVERGENCE.md"
- "evidence/interoperability-reference-target.json"
- "docs/INTEROPERABILITY_REFERENCE_CONTRACT.md"
- "tests/ARSAS.Tests/CanonicalLiveSclExportRegressionTests.cs"
- "tests/ARSAS.Tests/CanonicalSclReloadValidatorTests.cs"
- ".github/workflows/scl-interoperability-r7.yml"
Expand Down Expand Up @@ -52,7 +52,7 @@ jobs:
shell: pwsh
run: |
$lock = Get-Content .\ARSAS\engines\ARIEC61850.lock.json -Raw | ConvertFrom-Json
$convergence = Get-Content .\ARSAS\evidence\iedscout-convergence-target.json -Raw | ConvertFrom-Json
$convergence = Get-Content .\ARSAS\evidence\interoperability-reference-target.json -Raw | ConvertFrom-Json
if ($lock.repository -ne 'masarray/ARIEC61850' -or
$lock.commit -notmatch '^[0-9a-f]{40}$') {
throw 'Invalid ARIEC61850 R7 lock.'
Expand All @@ -71,7 +71,7 @@ jobs:
[bool]$convergence.promotion.physicalRetestRequired -or
-not [bool]$convergence.promotion.mergeAllowedAfterPhysicalRetest -or
-not [bool]$convergence.promotion.physicalRetestPassed) {
throw 'IEDScout convergence single-source-of-truth does not match the physically proven merged-engine + ARSAS #324 authority.'
throw 'external IEC 61850 reference convergence single-source-of-truth does not match the physically proven merged-engine + ARSAS #324 authority.'
}
if ([int]$lock.sourcePullRequest -notin @(134, 135)) {
throw "Unexpected R7 engine source PR: $($lock.sourcePullRequest)"
Expand Down Expand Up @@ -111,7 +111,7 @@ jobs:
$cdcInference = Get-Content .\ARIEC61850\src\AR.Iec61850\Discovery\CdcInferenceEngine.cs -Raw
$consumer = Get-Content .\ARSAS\Services\NativeIec61850Client.CanonicalModel.cs -Raw
$capture = Get-Content .\ARSAS\Services\NativeIec61850Client.SmartDiscoveryCapture.cs -Raw
$convergence = Get-Content .\ARSAS\evidence\iedscout-convergence-target.json -Raw | ConvertFrom-Json
$convergence = Get-Content .\ARSAS\evidence\interoperability-reference-target.json -Raw | ConvertFrom-Json
$buildTargets = Get-Content .\ARSAS\Directory.Build.targets -Raw
$lifecycle = Get-Content .\ARSAS\Services\NativeIec61850Client.SmartDiscoveryLifecycle.cs -Raw
$sclClient = Get-Content .\ARSAS\Services\NativeIec61850Client.SclAssisted.cs -Raw
Expand Down Expand Up @@ -175,16 +175,16 @@ jobs:
$capture -match 'DiscoverDomainVariableTypeTreeNamesAsync' -or
$capture -match 'AddAdaptiveLogicalNodeSiblingProbeSignalsAsync' -or
$capture -match 'EnrichEngineeringUnitsAsync') {
throw 'IEDScout convergence source contract regressed: smart structure-first discovery or semantic SCL authority is missing, or a forbidden legacy browse path returned.'
throw 'external IEC 61850 reference convergence source contract regressed: smart structure-first discovery or semantic SCL authority is missing, or a forbidden legacy browse path returned.'
}

if ([int]$convergence.physicalReference.iedScoutCapture.associations -ne 1 -or
if ([int]$convergence.physicalReference.externalReferenceCapture.associations -ne 1 -or
[int]$convergence.physicalReference.rejectedLegacyArsasCapture.associations -ne 2 -or
-not [bool]$convergence.discoveryAcceptance.exactlyOneAssociation -or
-not [bool]$convergence.discoveryAcceptance.supplementalLegacyAssociationForbidden -or
-not [bool]$convergence.sclAcceptance.reopenInArsasRequired -or
-not [bool]$convergence.sclAcceptance.physicalReconnectRequired) {
throw 'IEDScout physical acceptance target was weakened.'
throw 'external IEC 61850 reference physical acceptance target was weakened.'
}

if ($consumer -notmatch 'LiveIedCanonicalModelBuilder\.Build\(model, communication, initialRead\)' -or
Expand Down Expand Up @@ -278,7 +278,7 @@ jobs:
throw "Portable EXE smoke test failed: $($process.ExitCode)"
}

$convergencePath = ".\ARSAS\evidence\iedscout-convergence-target.json"
$convergencePath = ".\ARSAS\evidence\interoperability-reference-target.json"
$convergenceHash = (Get-FileHash $convergencePath -Algorithm SHA256).Hash.ToLowerInvariant()
$convergence = Get-Content $convergencePath -Raw | ConvertFrom-Json

Expand Down Expand Up @@ -306,8 +306,8 @@ jobs:
path: |
ARSAS\dist\ARSAS-*-win-x64-portable.exe
ARSAS\dist\R7-SCL-INTEROP-BUILD.txt
ARSAS\evidence\iedscout-convergence-target.json
ARSAS\docs\IEDSCOUT_CONVERGENCE.md
ARSAS\evidence\interoperability-reference-target.json
ARSAS\docs\INTEROPERABILITY_REFERENCE_CONTRACT.md
ARSAS\TestResults\*.trx
if-no-files-found: error
retention-days: 14
2 changes: 1 addition & 1 deletion .github/workflows/smart-discovery-mainline-readiness.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- name: Verify R10 physical convergence authority
shell: powershell
run: |
$target = Get-Content .\evidence\iedscout-convergence-target.json -Raw | ConvertFrom-Json
$target = Get-Content .\evidence\interoperability-reference-target.json -Raw | ConvertFrom-Json
$lock = Get-Content .\engines\ARIEC61850.lock.json -Raw | ConvertFrom-Json

if ($target.status -ne 'physical-retest-passed-merge-ready' -or
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/smart-discovery-post-merge-production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- name: Verify R10 physical convergence authority
shell: powershell
run: |
$target = Get-Content .\evidence\iedscout-convergence-target.json -Raw | ConvertFrom-Json
$target = Get-Content .\evidence\interoperability-reference-target.json -Raw | ConvertFrom-Json
$lock = Get-Content .\engines\ARIEC61850.lock.json -Raw | ConvertFrom-Json

if ($target.status -ne 'physical-retest-passed-merge-ready' -or
Expand Down Expand Up @@ -86,7 +86,7 @@ jobs:
shell: powershell
run: |
New-Item -ItemType Directory -Force .\TestResults | Out-Null
$target = Get-Content .\evidence\iedscout-convergence-target.json -Raw | ConvertFrom-Json
$target = Get-Content .\evidence\interoperability-reference-target.json -Raw | ConvertFrom-Json
[ordered]@{
schemaVersion = 1
sourceCommit = $env:GITHUB_SHA
Expand Down
2 changes: 1 addition & 1 deletion docs/FAT_V2_IMPLEMENTATION_PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ Required regressions:
- identical duplicate source collapses safely;
- conflicting IED/AP sources block;
- fingerprint is order-independent;
- Siemens-like 36 ST + 22 MX fixture remains 58/58.
- Synthetic cross-LD 36 ST + 22 MX fixture remains 58/58.

### P4 — FAT workspace UX

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
# IEDScout Convergence Contract
# IEC 61850 Interoperability Reference Contract

## Product target

ARSAS targets IEDScout-equivalent IEC 61850 engineering semantics with lower wire cost where possible:
ARSAS targets independently verified IEC 61850 IEC 61850 engineering semantics with lower wire cost where possible:

1. one accepted MMS association and bounded structure-first discovery;
2. a complete canonical model with exact LN/DO/SDO/DA/FC identity;
3. Edition 2 IID / Edition 1 ICD that can be reopened by ARSAS, reconnect to the same relay, hydrate values without full discovery, and run configured static reporting.

The machine-readable authority is `evidence/iedscout-convergence-target.json`.
The machine-readable authority is `evidence/interoperability-reference-target.json`.

## Original reference provenance

The same-relay comparison was an authorized black-box measurement against a separately operated engineering tool. Its original name, source-specific labels and historical context remain verifiable in the immutable [pre-migration repository commit](https://github.com/masarray/arsas/commit/36a4b87a3c2f6d34f73fa36c8a8a6a59763bd435), original evidence blob `a853fd0ea115b320a648b1b2a52fe9a7f6af94cd`. This active contract uses neutral aliases **without changing which tool generated the historical reference**. The measurements are comparison inputs, not proof of source-code or interface lineage.

## Merged proven baseline

Expand Down Expand Up @@ -37,8 +41,8 @@ GetNamedVariableListAttributes and 64 Reads, while preserving 32 LD / 119 LN /
860 top-level DO / 906 DO+SDO / 4925 scalar leaves / 2 DataSets / 58 FCDA / 32
logical ReportControls / 1 SettingControl.

The same-relay IEDScout comparison remains about 417 confirmed requests, 119 GVA
and 156 Reads. ARSAS must not add traffic merely to imitate IEDScout.
The same-relay external black-box reference tool comparison remains about 417 confirmed requests, 119 GVA
and 156 Reads. ARSAS must not add traffic merely to imitate external black-box reference tool.

Forbidden regressions include a second discovery association, legacy supplemental
browse, a second full GetNameList sweep, recursive per-leaf GVA, and eager FC-root
Expand Down Expand Up @@ -98,7 +102,7 @@ unchanged:
- Ed2 exported `Val`: 3202;
- Ed1 exported `Val`: 3106.

IEDScout's golden file has about 1529 `Val` elements. A larger count is not
The external reference SCL file has about 1529 `Val` elements. A larger count is not
automatically better; the remaining task is semantic path/value comparison, not
count chasing.

Expand All @@ -118,7 +122,7 @@ The accepted representation remains:
R10 Ed2 is semantically correct but verbose:

- ARSAS: 119 LNodeType / 906 DOType / 752 DAType / about 731 KB;
- IEDScout reference: about 38 / 60 / 17 / about 247 KB.
- external black-box reference tool reference: about 38 / 60 / 17 / about 247 KB.

Next work may intern only templates with identical ordered semantic fingerprints.
Expanded model counts, FC ownership, values, DataSets/RCBs and round-trip behavior
Expand All @@ -133,7 +137,7 @@ model-generation change or explicit refresh.

### 3. Semantic Val diff

Compare ARSAS vs IEDScout by exact
Compare ARSAS vs external black-box reference tool by exact
`LD/LN/DO/SDO/DA/BDA/FC/bType/value` path, not raw XML position and not total
`Val` count.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"schemaVersion": 1,
"name": "IEDScout discovery and SCL convergence",
"name": "independent black-box reference tool discovery and SCL convergence",
"status": "physical-retest-passed-merge-ready",
"target": {
"discovery": "Reach IEDScout-like MMS discovery efficiency without sacrificing exact IEC 61850 model evidence.",
"discovery": "Reach reference-grade MMS discovery efficiency without sacrificing exact IEC 61850 model evidence.",
"model": "Build the canonical IEC 61850 model from structure-first MMS evidence with correct LN identity, DO/SDO hierarchy, FC ownership, DataSet/RCB semantics, and schema-aware CDC handling.",
"scl": "Save Edition 2 IID / Edition 1 ICD that reopens in ARSAS, reconnects to the relay, and is usable as trusted SCL."
},
Expand Down Expand Up @@ -39,7 +39,7 @@
"dataSets": 2,
"runtimeReportControls": 34,
"logicalSclReportControls": 32,
"iedScoutCapture": {
"externalReferenceCapture": {
"associations": 1,
"confirmedMmsRequests": 417,
"getVariableAccessAttributes": 119,
Expand All @@ -53,7 +53,7 @@
"reads": 6548,
"note": "Regression signature. A future field build showing this pattern is rejected."
},
"iedScoutSclReference": {
"externalSclReference": {
"lDevices": 32,
"logicalNodes": 119,
"dataSets": 2,
Expand All @@ -71,7 +71,7 @@
"secondFullGetNameListSweepForbidden": true,
"eagerInitialFcValueReadDuringStructuralDiscovery": false,
"typeStrategy": "LN/root structure first, bounded leaf fallback only when exact structure evidence is unavailable.",
"physicalPerformanceGate": "Compare request count, GVA count, Read count, peak outstanding calls, TTFI and total discovery time against IEDScout on the same relay."
"physicalPerformanceGate": "Compare request count, GVA count, Read count, peak outstanding calls, TTFI and total discovery time against independent black-box reference tool on the same relay."
},
"modelAcceptance": {
"prefixedLogicalNodeIdentityExamples": [
Expand Down Expand Up @@ -127,7 +127,7 @@
"diagnostic report",
"Ed2 SCL-assisted reuse diagnostic with projectionErrorSamples",
"Ed1 SCL-assisted reuse diagnostic with projectionErrorSamples",
"same-relay comparison against IEDScout"
"same-relay comparison against independent black-box reference tool"
],
"mergeAllowedAfterPhysicalRetest": true,
"physicalRetestPassed": true,
Expand Down Expand Up @@ -332,13 +332,13 @@
},
"saveTimeInstanceValues": {
"observedR9ExportValCount": 0,
"referenceIedScoutValCount": 1529,
"referenceSclValCount": 1529,
"status": "mechanism-physically-proven-semantic-diff-open",
"rule": "Keep structural discovery read-free; acquire bounded safe FC-root values only during explicit Save SCL and verify resulting instance evidence physically.",
"r10InstanceEvidence": 3854,
"r10Edition2ValCount": 3202,
"r10Edition1ValCount": 3106,
"note": "Save-time value enrichment is physically proven. More Val elements than IEDScout is not treated as automatically better; exact semantic path/value comparison remains open."
"note": "Save-time value enrichment is physically proven. More Val elements than independent black-box reference tool is not treated as automatically better; exact semantic path/value comparison remains open."
},
"templateReuse": {
"status": "next-improvement",
Expand All @@ -349,7 +349,7 @@
"daType": 752,
"fileBytes": 731266
},
"iedScoutReference": {
"externalReference": {
"lNodeType": 38,
"doType": 60,
"daType": 17,
Expand Down
Loading