Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
3ccf92e
Add versioned declarative SV profile manifest engine
masarray Jul 22, 2026
04f32a9
Add declarative SV profile manifest regression tests
masarray Jul 22, 2026
145f2b4
Add safe declarative profile manifest example
masarray Jul 22, 2026
5a1634b
Document declarative SV profile manifest safety model
masarray Jul 22, 2026
1bacb76
Harden generic SV scaling evidence
masarray Jul 22, 2026
3f0529c
Remove profile-manifest direction
masarray Jul 22, 2026
98cddbb
Remove profile-manifest example
masarray Jul 22, 2026
24c267c
Remove declarative profile manifest engine
masarray Jul 22, 2026
ee9cd83
Remove profile-manifest tests
masarray Jul 22, 2026
8eefbef
Add generic SV seqOfData inspector
masarray Jul 22, 2026
b927457
Test generic SV payload inspection contract
masarray Jul 22, 2026
771874f
Align scaling tests with generic SCL-driven policy
masarray Jul 22, 2026
05ccc0b
Add generic SV ASDU inspection model
masarray Jul 22, 2026
3f9420c
Test generic SV ASDU inspection
masarray Jul 22, 2026
8609a38
Document generic ArSubsv audit and roadmap
masarray Jul 22, 2026
4a4c008
Add generic Subscriber presentation layer
masarray Jul 22, 2026
7171d47
Present unbound SV payloads generically in Subscriber UI
masarray Jul 22, 2026
b03c5e8
Keep generic explorer roadmap vendor-neutral
masarray Jul 22, 2026
841ccec
Test generic Subscriber presentation contract
masarray Jul 22, 2026
7082bb2
Keep generic payload contract terminology neutral
masarray Jul 22, 2026
12dd0ab
Remove Subscriber-only test from engine test project
masarray Jul 22, 2026
451e8b6
Define ARIEC61850 sibling project ownership
masarray Jul 23, 2026
8a18c46
Fail fast when the ARIEC61850 sibling is missing
masarray Jul 23, 2026
0c559f4
Reference the sibling ARIEC61850 engine from Publisher
masarray Jul 23, 2026
7de338e
Reference the sibling ARIEC61850 engine from Subscriber
masarray Jul 23, 2026
da186cf
Run ARSVIN regression tests against sibling ARIEC61850
masarray Jul 23, 2026
55c96eb
Remove embedded engine from the active solution
masarray Jul 23, 2026
9d24735
Keep the solution application-only while project references resolve t…
masarray Jul 23, 2026
265ee0f
Measure coverage against sibling ARIEC61850 core
masarray Jul 23, 2026
e507006
Build CI against the paired ARIEC61850 sibling branch
masarray Jul 23, 2026
68ec1da
Analyze ARSVIN with the paired ARIEC61850 sibling
masarray Jul 23, 2026
7490901
Bootstrap and build against the sibling ARIEC61850 engine
masarray Jul 23, 2026
3a5424f
Allow paired sibling restore during the unmerged migration
masarray Jul 23, 2026
1d6c634
Publish paired ARSVIN and ARIEC61850 builds with engine provenance
masarray Jul 23, 2026
45a3f5d
Record sibling ARIEC61850 provenance in the release SBOM
masarray Jul 23, 2026
85bd453
Keep paired engine provenance inside release packages and SBOM
masarray Jul 23, 2026
74b1f35
Enforce ARIEC61850 ownership in derived applications
masarray Jul 23, 2026
19a4c29
Validate engine ownership and safely resolve paired engine provenance
masarray Jul 23, 2026
d8012b2
Enforce engine ownership in paired CI
masarray Jul 23, 2026
c992b91
Allow application namespaces while blocking reusable engine domains
masarray Jul 23, 2026
03ef674
Document paired local engine integration and testing
masarray Jul 23, 2026
b73c0c9
Preserve paired application build diagnostics as CI artifacts
masarray Jul 23, 2026
def7883
Capture paired restore failures in CI artifacts
masarray Jul 23, 2026
871e7cf
Use true sibling checkouts for paired CI builds
masarray Jul 23, 2026
6c6091f
Use true sibling checkouts for CodeQL analysis
masarray Jul 23, 2026
2416043
Remove migrated generic ASDU inspector from embedded engine
masarray Jul 23, 2026
456b5d8
Remove migrated generic payload inspector from embedded engine
masarray Jul 23, 2026
45e9cca
Restore inactive embedded scaling file to main baseline
masarray Jul 23, 2026
b1d0800
Document migrated publisher and subscriber core contracts
masarray Jul 23, 2026
cd44d1f
Remove migrated Sampled Values quality encoding from embedded engine
masarray Jul 23, 2026
3e5a5cb
Remove migrated sample counter policy from embedded engine
masarray Jul 23, 2026
97aa667
Remove migrated SV PCAP exporter from embedded engine
masarray Jul 23, 2026
a86ad6f
Remove migrated SV frame preview from embedded engine
masarray Jul 23, 2026
3e6a692
Remove migrated SV publisher validation from embedded engine
masarray Jul 23, 2026
f59ed33
Remove migrated SV publisher profile from embedded engine
masarray Jul 23, 2026
2270844
Remove migrated SV payload builder from embedded engine
masarray Jul 23, 2026
f1a0d1e
Record migrated Subscriber observation and evidence contracts
masarray Jul 23, 2026
2f131ee
Record migrated multi-ASDU session behavior
masarray Jul 23, 2026
be7263a
Pin and validate the paired ARIEC61850 engine revision
masarray Jul 24, 2026
3322bc7
Advance the pinned engine and correct IEC quality regression evidence
masarray Jul 24, 2026
85e2c02
Gate paired coverage by exercised code instead of engine growth
masarray Jul 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
119 changes: 97 additions & 22 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ permissions:

jobs:
public-content:
name: Validate licensing, provenance, and public wording
name: Validate licensing, provenance, wording, and engine ownership
runs-on: ubuntu-24.04
steps:
- name: Checkout
Expand All @@ -26,76 +26,151 @@ jobs:
continue-on-error: true
run: python3 scripts/validate-public-neutrality.py

- name: Upload terminology validation evidence
- name: Validate ARIEC61850 engine ownership boundary
id: ownership
continue-on-error: true
run: python3 scripts/validate-engine-ownership.py

- name: Upload public and ownership validation evidence
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: arsvin-public-neutrality-report
path: artifacts/public-neutrality-report.txt
name: arsvin-public-and-engine-ownership-reports
path: |
artifacts/public-neutrality-report.txt
artifacts/engine-ownership-report.txt
if-no-files-found: error
retention-days: 14

- name: Enforce terminology validation result
if: steps.neutrality.outcome == 'failure'
- name: Enforce public and ownership validation results
if: steps.neutrality.outcome == 'failure' || steps.ownership.outcome == 'failure'
run: exit 1

build-test:
name: Build, test, and validate site
name: Build, test, and validate pinned engine integration
needs: public-content
runs-on: windows-2025
defaults:
run:
working-directory: arsvin
env:
ARIEC61850_ROOT: ${{ github.workspace }}\ARIEC61850
steps:
- name: Checkout
- name: Checkout ARSVIN into paired workspace
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
with:
path: arsvin

- name: Resolve pinned ARIEC61850 revision
id: engine_pin
shell: pwsh
run: |
$pin = .\scripts\resolve-engine-pin.ps1 -AsObject
"repository=$($pin.Repository)" | Add-Content $env:GITHUB_OUTPUT
"ref=$($pin.Ref)" | Add-Content $env:GITHUB_OUTPUT
"commit=$($pin.Commit)" | Add-Content $env:GITHUB_OUTPUT

- name: Checkout pinned sibling ARIEC61850
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
with:
repository: ${{ steps.engine_pin.outputs.repository }}
ref: ${{ steps.engine_pin.outputs.commit }}
path: ARIEC61850

- name: Record and verify paired engine revision
shell: pwsh
run: |
$engineSha = (git -C "$env:ARIEC61850_ROOT" rev-parse HEAD).Trim().ToLowerInvariant()
$expected = '${{ steps.engine_pin.outputs.commit }}'.ToLowerInvariant()
if ($engineSha -ne $expected) {
throw "Pinned engine mismatch. Expected $expected, found $engineSha."
}
"ARIEC61850_REF=${{ steps.engine_pin.outputs.ref }}" | Out-File artifacts-engine-revision.txt -Encoding utf8
"ARIEC61850_EXPECTED_SHA=$expected" | Add-Content artifacts-engine-revision.txt
"ARIEC61850_ACTUAL_SHA=$engineSha" | Add-Content artifacts-engine-revision.txt
Get-Content artifacts-engine-revision.txt

- name: Setup .NET
uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5
with:
dotnet-version: 8.0.4xx
cache: true
cache-dependency-path: |
Directory.Packages.props
src/**/packages.lock.json
tests/**/packages.lock.json
arsvin/Directory.Packages.props
arsvin/src/**/packages.lock.json
arsvin/tests/**/packages.lock.json

- name: Verify current licensing and public wording
run: python scripts/verify-current-license.py

- name: Validate engine ownership boundary
run: python scripts/validate-engine-ownership.py

- name: Build public site and HTML documentation
run: python scripts/build-public-site.py --output artifacts/public-site

- name: Validate public site
shell: pwsh
run: .\scripts\validate-public-site.ps1 -SiteRoot artifacts/public-site

- name: Restore locked NuGet dependency graph
run: dotnet restore ARSVIN.sln --locked-mode
- name: Restore dependency graph
shell: pwsh
run: |
New-Item -ItemType Directory -Path artifacts/build-logs -Force | Out-Null
dotnet restore ARSVIN.sln 2>&1 |
Tee-Object -FilePath artifacts/build-logs/restore.log
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }

- name: Upload committed NuGet lock evidence
- name: Upload NuGet lock and paired engine revision evidence
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: arsvin-nuget-lockfiles
name: arsvin-dependency-evidence
path: |
src/**/packages.lock.json
tests/**/packages.lock.json
arsvin/engines/ARIEC61850.lock.json
arsvin/src/**/packages.lock.json
arsvin/tests/**/packages.lock.json
arsvin/artifacts-engine-revision.txt
if-no-files-found: error
retention-days: 7

- name: Build Publisher with warnings as errors
run: dotnet build src/ARSVIN/ARSVIN.csproj -c Release --no-restore -warnaserror
shell: pwsh
run: |
dotnet build src/ARSVIN/ARSVIN.csproj -c Release --no-restore -warnaserror 2>&1 |
Tee-Object -FilePath artifacts/build-logs/publisher-build.log
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }

- name: Build Subscriber with warnings as errors
run: dotnet build src/ARSVIN.Subscriber/ARSVIN.Subscriber.csproj -c Release --no-restore -warnaserror
shell: pwsh
run: |
dotnet build src/ARSVIN.Subscriber/ARSVIN.Subscriber.csproj -c Release --no-restore -warnaserror 2>&1 |
Tee-Object -FilePath artifacts/build-logs/subscriber-build.log
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }

- name: Upload paired restore and build diagnostics
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: arsvin-paired-build-logs
path: arsvin/artifacts/build-logs
if-no-files-found: warn
retention-days: 14

- name: Test with whole-engine and protocol-core coverage gates
- name: Test against pinned ARIEC61850 with integration coverage gates
shell: pwsh
run: .\scripts\test-with-coverage.ps1 -MinimumWholeEngineLineCoverage 14.25 -MinimumLineCoverage 72.5 -NoRestore
run: |
.\scripts\test-with-coverage.ps1 `
-MinimumWholeEngineCoveredLines 3000 `
-MinimumProtocolCoreCoveredLines 2300 `
-MinimumLineCoverage 72.5 `
-NoRestore

- name: Upload test and coverage evidence
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: arsvin-test-evidence
path: artifacts/test-results
path: arsvin/artifacts/test-results
if-no-files-found: warn
retention-days: 14

Expand Down
49 changes: 40 additions & 9 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,64 @@ permissions:

jobs:
analyze:
name: Analyze C# solution
name: Analyze pinned paired C# solution
runs-on: windows-2025
defaults:
run:
working-directory: arsvin
env:
ARIEC61850_ROOT: ${{ github.workspace }}\ARIEC61850
steps:
- name: Checkout
- name: Checkout ARSVIN into paired workspace
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
with:
path: arsvin

- name: Resolve pinned ARIEC61850 revision
id: engine_pin
shell: pwsh
run: |
$pin = .\scripts\resolve-engine-pin.ps1 -AsObject
"repository=$($pin.Repository)" | Add-Content $env:GITHUB_OUTPUT
"commit=$($pin.Commit)" | Add-Content $env:GITHUB_OUTPUT

- name: Checkout pinned sibling ARIEC61850
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
with:
repository: ${{ steps.engine_pin.outputs.repository }}
ref: ${{ steps.engine_pin.outputs.commit }}
path: ARIEC61850

- name: Verify pinned engine commit
shell: pwsh
run: |
$actual = (git -C "$env:ARIEC61850_ROOT" rev-parse HEAD).Trim().ToLowerInvariant()
$expected = '${{ steps.engine_pin.outputs.commit }}'.ToLowerInvariant()
if ($actual -ne $expected) {
throw "Pinned engine mismatch. Expected $expected, found $actual."
}

- name: Setup .NET
uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5
with:
dotnet-version: 8.0.4xx
cache: true
cache-dependency-path: |
Directory.Packages.props
src/**/packages.lock.json
tests/**/packages.lock.json
arsvin/Directory.Packages.props
arsvin/src/**/packages.lock.json
arsvin/tests/**/packages.lock.json

- name: Initialize CodeQL
uses: github/codeql-action/init@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
with:
languages: csharp
build-mode: manual

- name: Restore locked solution dependency graph
run: dotnet restore ARSVIN.sln --locked-mode
- name: Restore pinned paired solution dependency graph
run: dotnet restore ARSVIN.sln

- name: Build solution with warnings as errors
- name: Build pinned paired solution with warnings as errors
run: dotnet build ARSVIN.sln -c Release --no-restore -warnaserror

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
uses: github/codeql-action/analyze@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
6 changes: 0 additions & 6 deletions ARSVIN.sln
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ARSVIN.Engine", "src\ARSVIN.Engine\ARSVIN.Engine.csproj", "{B6A2A1F7-2B1A-47B5-9C73-1A94C60D0B8E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ARSVIN", "src\ARSVIN\ARSVIN.csproj", "{C2A1F2F6-4C1A-4D6A-A3F1-1E4FD13C4D01}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ARSVIN.Subscriber", "src\ARSVIN.Subscriber\ARSVIN.Subscriber.csproj", "{A9F2E511-7D62-4C74-99CF-0E59B8D51377}"
Expand All @@ -16,10 +14,6 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B6A2A1F7-2B1A-47B5-9C73-1A94C60D0B8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B6A2A1F7-2B1A-47B5-9C73-1A94C60D0B8E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B6A2A1F7-2B1A-47B5-9C73-1A94C60D0B8E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B6A2A1F7-2B1A-47B5-9C73-1A94C60D0B8E}.Release|Any CPU.Build.0 = Release|Any CPU
{C2A1F2F6-4C1A-4D6A-A3F1-1E4FD13C4D01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C2A1F2F6-4C1A-4D6A-A3F1-1E4FD13C4D01}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C2A1F2F6-4C1A-4D6A-A3F1-1E4FD13C4D01}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down
16 changes: 15 additions & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@
<ContinuousIntegrationBuild Condition="'$(CI)' == 'true'">true</ContinuousIntegrationBuild>
<Deterministic>true</Deterministic>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
<RestoreLockedMode Condition="'$(CI)' == 'true'">true</RestoreLockedMode>
<!--
The sibling-project graph differs from the retired embedded engine graph. During this
unmerged migration PR, restore is intentionally unlocked so local and CI paired builds
can refresh dependency assets. Lock files will be regenerated after the paired branches
are accepted and pinned to reviewed commits.
-->
<RestoreLockedMode>false</RestoreLockedMode>
<VersionPrefix>0.4.0</VersionPrefix>
<SourceRevisionId Condition="'$(SourceRevisionId)' == '' and '$(GITHUB_SHA)' != ''">$(GITHUB_SHA)</SourceRevisionId>
<IncludeSourceRevisionInInformationalVersion>true</IncludeSourceRevisionInInformationalVersion>
Expand All @@ -17,5 +23,13 @@
<Authors>Ari Sulistiono</Authors>
<Company>Ari Sulistiono</Company>
<Copyright>Copyright © 2026 Ari Sulistiono</Copyright>

<!--
ARSVIN and ArSubsv are derived applications. Reusable IEC 61850 logic is owned by
the sibling ARIEC61850 repository rather than an embedded copy in this repository.
-->
<ARIEC61850_ROOT Condition="'$(ARIEC61850_ROOT)' == ''">$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\ARIEC61850'))</ARIEC61850_ROOT>
<ARIEC61850_CORE_PROJECT>$(ARIEC61850_ROOT)\src\AR.Iec61850\AR.Iec61850.csproj</ARIEC61850_CORE_PROJECT>
<ARIEC61850_NPCAP_PROJECT>$(ARIEC61850_ROOT)\src\AR.Iec61850.Transports.Npcap\AR.Iec61850.Transports.Npcap.csproj</ARIEC61850_NPCAP_PROJECT>
</PropertyGroup>
</Project>
10 changes: 10 additions & 0 deletions Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project>
<Target Name="ValidateARIEC61850Sibling"
BeforeTargets="PrepareForBuild"
Condition="'$(MSBuildProjectName)' == 'ARSVIN' or '$(MSBuildProjectName)' == 'ARSVIN.Subscriber' or '$(MSBuildProjectName)' == 'ARSVIN.Tests'">
<Error Condition="!Exists('$(ARIEC61850_CORE_PROJECT)')"
Text="ARIEC61850 sibling repository was not found. Expected core project: $(ARIEC61850_CORE_PROJECT). Clone https://github.com/masarray/ARIEC61850 beside this repository or pass -p:ARIEC61850_ROOT=&quot;X:\path\ARIEC61850&quot;." />
<Error Condition="!Exists('$(ARIEC61850_NPCAP_PROJECT)')"
Text="ARIEC61850 Npcap transport project was not found. Expected: $(ARIEC61850_NPCAP_PROJECT)." />
</Target>
</Project>
Loading
Loading