Skip to content

Commit 85d43a0

Browse files
authored
Merge pull request #9 from masarray/architecture/v1.4.0-beta.1
Introduce immutable runtime snapshots and PCAP replay for v1.4.0-beta.1
2 parents d4a35f2 + 1461584 commit 85d43a0

22 files changed

Lines changed: 1396 additions & 84 deletions

‎.github/ISSUE_TEMPLATE/bug.yml‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: Bug report
2-
description: Report a reproducible runtime, protocol, UI, or packaging defect.
2+
description: Report a reproducible runtime, protocol, UI, replay, or packaging defect.
33
title: "[Bug]: "
44
labels: [bug, triage]
55
body:
@@ -11,7 +11,7 @@ body:
1111
id: version
1212
attributes:
1313
label: Process Bus Insight version
14-
placeholder: 1.3.0-beta.2 or commit SHA
14+
placeholder: 1.4.0-beta.1 or commit SHA
1515
validations:
1616
required: true
1717
- type: dropdown
@@ -20,6 +20,7 @@ body:
2020
label: Area
2121
options:
2222
- SV analyzer / waveform / phasor
23+
- PCAP replay / runtime snapshot
2324
- GOOSE inspector
2425
- PTP / timing context
2526
- SCL validation
@@ -33,18 +34,18 @@ body:
3334
id: environment
3435
attributes:
3536
label: Environment
36-
description: Windows version, Npcap version, adapter type, and capture path.
37-
placeholder: Windows 11 x64; Npcap 1.x; Intel NIC via TAP
37+
description: Windows version, Npcap version, adapter type, and capture/replay path.
38+
placeholder: Windows 11 x64; Npcap 1.x; Intel NIC via TAP or sanitized PCAP replay
3839
validations:
3940
required: true
4041
- type: textarea
4142
id: reproduce
4243
attributes:
4344
label: Reproduction steps
4445
placeholder: |
45-
1. Start capture...
46+
1. Start capture or replay...
4647
2. Select stream...
47-
3. Change publisher setting...
48+
3. Change publisher setting or replay the sanitized file...
4849
validations:
4950
required: true
5051
- type: textarea

‎.github/workflows/candidate-package.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ env:
2929
jobs:
3030
candidate:
3131
name: Build verified Windows x64 candidate
32-
if: github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'stabilization/')
32+
if: github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'stabilization/') || startsWith(github.head_ref, 'architecture/')
3333
runs-on: windows-latest
3434
timeout-minutes: 35
3535

‎.github/workflows/release-package.yml‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ on:
44
workflow_dispatch:
55
inputs:
66
version:
7-
description: Version label, for example 1.3.0-beta.2
7+
description: Version label, for example 1.4.0-beta.1
88
required: true
9-
default: 1.3.0-beta.2
9+
default: 1.4.0-beta.1
1010
publish_release:
1111
description: Create or update a GitHub Release
1212
required: true
@@ -25,7 +25,7 @@ on:
2525
release_notes_file:
2626
description: Markdown file used as release body
2727
required: true
28-
default: docs/RELEASE_NOTES_v1.3.0-beta.2.md
28+
default: docs/RELEASE_NOTES_v1.4.0-beta.1.md
2929
push:
3030
tags:
3131
- "v*"
@@ -130,7 +130,7 @@ jobs:
130130
$sha = "artifacts/release/SHA256SUMS.txt"
131131
$manifest = "artifacts/release/release-manifest.json"
132132
$notesFile = '${{ github.event.inputs.release_notes_file }}'
133-
if ([string]::IsNullOrWhiteSpace($notesFile)) { $notesFile = 'docs/RELEASE_NOTES_v1.3.0-beta.2.md' }
133+
if ([string]::IsNullOrWhiteSpace($notesFile)) { $notesFile = 'docs/RELEASE_NOTES_v1.4.0-beta.1.md' }
134134
if (-not (Test-Path $notesFile)) { throw "Release notes file not found: $notesFile" }
135135
136136
$releaseArgs = @('release', 'create', $tag, $zip, $sha, $manifest, '--title', "Process Bus Insight $tag", '--notes-file', $notesFile, '--target', '${{ github.sha }}')
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
name: Runtime architecture
2+
3+
on:
4+
pull_request:
5+
branches: [main]
6+
paths:
7+
- "src/ProcessBus.Iec61850.Raw/Runtime/**"
8+
- "src/ProcessBus.Iec61850.Raw/Replay/**"
9+
- "tests/ProcessBus.Tests/Pcap*Tests.cs"
10+
- "tests/ProcessBus.Tests/AnalyzerRuntimeSnapshotSourceTests.cs"
11+
- ".github/workflows/runtime-architecture.yml"
12+
schedule:
13+
- cron: "17 3 * * 4"
14+
workflow_dispatch:
15+
inputs:
16+
iterations:
17+
description: Number of deterministic architecture passes
18+
required: true
19+
default: "3"
20+
21+
permissions:
22+
contents: read
23+
24+
concurrency:
25+
group: runtime-architecture-${{ github.workflow }}-${{ github.ref }}
26+
cancel-in-progress: true
27+
28+
env:
29+
DOTNET_NOLOGO: true
30+
DOTNET_CLI_TELEMETRY_OPTOUT: true
31+
32+
jobs:
33+
architecture:
34+
name: Immutable snapshot and PCAP replay gate
35+
runs-on: windows-latest
36+
timeout-minutes: 30
37+
38+
steps:
39+
- name: Checkout
40+
uses: actions/checkout@v4
41+
42+
- name: Setup .NET
43+
uses: actions/setup-dotnet@v5
44+
with:
45+
dotnet-version: 8.0.x
46+
47+
- name: Restore
48+
run: dotnet restore .\ProcessBusSuite.sln
49+
50+
- name: Build
51+
run: dotnet build .\ProcessBusSuite.sln -c Release --no-restore /p:ContinuousIntegrationBuild=true
52+
53+
- name: Repeat runtime architecture suite
54+
shell: pwsh
55+
run: |
56+
$requested = '${{ github.event.inputs.iterations }}'
57+
$iterations = 3
58+
if (-not [string]::IsNullOrWhiteSpace($requested)) {
59+
$parsed = 0
60+
if (-not [int]::TryParse($requested, [ref]$parsed)) {
61+
throw "Invalid iterations value: $requested"
62+
}
63+
$iterations = [Math]::Clamp($parsed, 1, 20)
64+
}
65+
66+
New-Item -ItemType Directory -Path .\TestResults\RuntimeArchitecture -Force | Out-Null
67+
Write-Host "Runtime architecture iterations: $iterations"
68+
69+
for ($iteration = 1; $iteration -le $iterations; $iteration++) {
70+
Write-Host "=== Runtime architecture pass $iteration/$iterations ==="
71+
dotnet test .\tests\ProcessBus.Tests\ProcessBus.Tests.csproj `
72+
-c Release `
73+
--no-build `
74+
--filter "Category=RuntimeArchitecture" `
75+
--logger "trx;LogFileName=runtime-architecture-$iteration.trx" `
76+
--results-directory .\TestResults\RuntimeArchitecture
77+
78+
if ($LASTEXITCODE -ne 0) {
79+
throw "Runtime architecture pass $iteration failed."
80+
}
81+
}
82+
83+
- name: Upload runtime architecture evidence
84+
if: always()
85+
uses: actions/upload-artifact@v7
86+
with:
87+
name: runtime-architecture-${{ github.run_id }}
88+
path: TestResults/RuntimeArchitecture/**
89+
if-no-files-found: error
90+
retention-days: 30

‎CHANGELOG.md‎

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,35 @@ All notable changes are documented here. The project follows Semantic Versioning
66

77
### Planned
88

9-
- Golden PCAP replay corpus with sanitized multi-stream scenarios
9+
- Sanitized golden PCAP/PCAPNG replay corpus with broader multi-vendor scenarios
1010
- Further decomposition of the analyzer runtime and WPF workspace
1111
- Expanded SCL multi-vendor validation
1212
- Evidence export for FAT/SAT reports
1313

14+
## [1.4.0-beta.1] - 2026-07-11
15+
16+
### Added
17+
18+
- Immutable selected-stream runtime generations with copied waveform, analog, identity, and diagnostic evidence
19+
- Atomic runtime snapshot publisher for coherent consumer reads
20+
- Classic Ethernet PCAP replay through the same raw decoder/analyzer path used by live Npcap capture
21+
- Microsecond and nanosecond PCAP timestamp variants in little-endian and big-endian formats
22+
- Bounded rejection for unsupported link types, invalid headers, oversized records, and truncated captures
23+
- Deterministic runtime-architecture tests covering replay timing, snapshot immutability, and three-stream isolation
24+
- Dedicated Runtime Architecture GitHub Actions gate with downloadable TRX evidence
25+
- Release-candidate packaging support for `architecture/*` branches
26+
27+
### Changed
28+
29+
- Release and documentation versioning use `1.4.0-beta.1`
30+
- Runtime architecture now exposes a coherent publication boundary instead of requiring consumers to retain mutable analyzer display models
31+
- Offline replay is explicitly treated as a reproducibility path, not a separate decoder or a traffic publisher
32+
33+
### Limitations
34+
35+
- PCAPNG is not yet supported by the first replay reader
36+
- The internal analyzer remains partly monolithic; complete per-stream runtime extraction and live UI migration continue in later v1.4 builds
37+
1438
## [1.3.0-beta.2] - 2026-07-10
1539

1640
### Added
@@ -58,6 +82,7 @@ All notable changes are documented here. The project follows Semantic Versioning
5882

5983
- Hardened BER parsing, Npcap lifecycle, release version propagation, and public-repository packaging.
6084

61-
[Unreleased]: https://github.com/masarray/DigSubAnalyzer/compare/v1.3.0-beta.2...HEAD
85+
[Unreleased]: https://github.com/masarray/DigSubAnalyzer/compare/v1.4.0-beta.1...HEAD
86+
[1.4.0-beta.1]: https://github.com/masarray/DigSubAnalyzer/compare/v1.3.0-beta.2...v1.4.0-beta.1
6287
[1.3.0-beta.2]: https://github.com/masarray/DigSubAnalyzer/compare/v1.3.0-beta.1...v1.3.0-beta.2
6388
[1.3.0-beta.1]: https://github.com/masarray/DigSubAnalyzer/releases/tag/v1.3.0-beta.1

‎Directory.Build.props‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
<NeutralLanguage>en</NeutralLanguage>
1111

1212
<!-- Public beta version. Release builds may override these properties from the tag. -->
13-
<VersionPrefix Condition="'$(VersionPrefix)' == ''">1.3.0</VersionPrefix>
14-
<VersionSuffix Condition="'$(VersionSuffix)' == ''">beta.2</VersionSuffix>
13+
<VersionPrefix Condition="'$(VersionPrefix)' == ''">1.4.0</VersionPrefix>
14+
<VersionSuffix Condition="'$(VersionSuffix)' == ''">beta.1</VersionSuffix>
1515
<Version Condition="'$(Version)' == ''">$(VersionPrefix)-$(VersionSuffix)</Version>
1616
<PackageVersion Condition="'$(PackageVersion)' == ''">$(Version)</PackageVersion>
1717
<AssemblyVersion Condition="'$(AssemblyVersion)' == ''">$(VersionPrefix).0</AssemblyVersion>

‎README.md‎

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
[![CI](https://github.com/masarray/DigSubAnalyzer/actions/workflows/ci.yml/badge.svg)](https://github.com/masarray/DigSubAnalyzer/actions/workflows/ci.yml)
44
[![Runtime Stability](https://github.com/masarray/DigSubAnalyzer/actions/workflows/runtime-stability.yml/badge.svg)](https://github.com/masarray/DigSubAnalyzer/actions/workflows/runtime-stability.yml)
5+
[![Runtime Architecture](https://github.com/masarray/DigSubAnalyzer/actions/workflows/runtime-architecture.yml/badge.svg)](https://github.com/masarray/DigSubAnalyzer/actions/workflows/runtime-architecture.yml)
56
[![CodeQL](https://github.com/masarray/DigSubAnalyzer/actions/workflows/codeql.yml/badge.svg)](https://github.com/masarray/DigSubAnalyzer/actions/workflows/codeql.yml)
67
[![GitHub Pages](https://github.com/masarray/DigSubAnalyzer/actions/workflows/pages.yml/badge.svg)](https://github.com/masarray/DigSubAnalyzer/actions/workflows/pages.yml)
78
[![Release Package](https://github.com/masarray/DigSubAnalyzer/actions/workflows/release-package.yml/badge.svg)](https://github.com/masarray/DigSubAnalyzer/actions/workflows/release-package.yml)
@@ -12,9 +13,9 @@
1213

1314
**Process Bus Insight** is a free, open-source, receive-only **IEC 61850 Process Bus analyzer for Windows**. It provides engineering visibility into **Sampled Values (SV)**, **GOOSE**, **PTPv2 timing context**, and **SCL expected-vs-observed validation** for FAT, SAT, commissioning, interoperability checks, and troubleshooting.
1415

15-
The project is currently released as a **public beta**. Its design goal is field clarity without overstating measurement confidence: identify live publishers, inspect protocol evidence, isolate unhealthy streams, compare observed traffic against SCL, and capture defensible findings.
16+
The project is currently released as a **public beta**. Its design goal is field clarity without overstating measurement confidence: identify live publishers, inspect protocol evidence, isolate unhealthy streams, reproduce captured traffic offline, compare observed traffic against SCL, and capture defensible findings.
1617

17-
> **Timing confidence:** normal Windows/Npcap timestamps are software based. Arrival timing is useful for screening and troubleshooting, but is not certification-grade jitter evidence unless the capture path is validated with appropriate hardware timestamping, TAP, or trusted timing equipment.
18+
> **Timing confidence:** normal Windows/Npcap timestamps and replayed capture timestamps are software evidence. Arrival timing is useful for screening and troubleshooting, but is not certification-grade jitter evidence unless the capture path is validated with appropriate hardware timestamping, TAP, or trusted timing equipment.
1819
1920
![Process Bus Insight analyzer overview](docs/screenshot/analyzer-overview.webp)
2021

@@ -27,6 +28,8 @@ Current capabilities include:
2728
| Area | Capability |
2829
| --- | --- |
2930
| SV analyzer | Multi-stream discovery, APPID/svID/MAC/VLAN/confRev evidence, selected-stream workspace, raw decoded sample waveform, RMS, phasor, sequence diagnostics, shape/distortion indication, and selectable scope windows. |
31+
| Runtime snapshots | Immutable selected-stream generations containing copied identity, waveform, analog, phasor, shape, and diagnostic evidence for coherent consumer reads. |
32+
| PCAP replay | Bounded classic Ethernet PCAP replay through the same raw decoder/analyzer entry point used by live Npcap capture. |
3033
| GOOSE inspector | Publisher discovery, stNum/sqNum tracking, event timeline, typed `allData` decoding, change summaries, and SCL-assisted semantic context. |
3134
| PTP visibility | Passive PTPv2 message context, grandmaster/domain evidence where available, freshness wording, and timestamp-confidence boundaries. |
3235
| SCL validation | Load SCD/ICD/CID files and compare expected publishers/streams against observed APPID, destination MAC, VLAN, svID, confRev, and related evidence. |
@@ -40,6 +43,7 @@ Wireshark remains an essential packet-analysis tool. Process Bus Insight focuses
4043
- Is the observed APPID, MAC, VLAN, svID, or confRev consistent with the SCL design?
4144
- Is the problem owned by the stream, publisher, timing source, adapter, or capture path?
4245
- Are waveform, RMS, and phasor values coming from the same selected stream?
46+
- Can a sanitized capture reproduce the same decoder and runtime behavior away from site?
4347
- What evidence can be copied into a FAT/SAT finding without overclaiming timing accuracy?
4448

4549
## Download and run
@@ -54,7 +58,7 @@ Wireshark remains an essential packet-analysis tool. Process Bus Insight focuses
5458
Current public-beta package naming:
5559

5660
```text
57-
ProcessBusInsight-v1.3.0-beta.2-win-x64-portable.zip
61+
ProcessBusInsight-v1.4.0-beta.1-win-x64-portable.zip
5862
SHA256SUMS.txt
5963
release-manifest.json
6064
```
@@ -66,19 +70,18 @@ See [`docs/QUICK_START.md`](docs/QUICK_START.md) for the field checklist.
6670
## Architecture
6771

6872
```text
69-
Process Bus / TAP / Mirror Port
70-
↓
71-
Npcap raw Ethernet capture
72-
↓
73-
ProcessBus.Iec61850.Raw
74-
SV / GOOSE / PTP decode and per-stream runtime
75-
↓
76-
ProcessBus.Core immutable display models
77-
↓
78-
ProcessBus.App.Wpf engineering workspaces
73+
Process Bus / TAP / Mirror Port ──> Npcap raw Ethernet capture ─┐
74+
├─> ProcessBus.Iec61850.Raw
75+
Classic Ethernet PCAP ───────────> bounded replay reader ───────┘ SV / GOOSE / PTP decode
76+
↓
77+
immutable runtime generation
78+
↓
79+
WPF / tests / future export
7980
```
8081

81-
The selected SV stream is the source of truth for waveform, RMS, phasor, and stream details. Per-stream state must remain isolated; UI refresh must never combine values from different publishers. See [`docs/architecture/STREAM_RUNTIME.md`](docs/architecture/STREAM_RUNTIME.md).
82+
The selected SV stream is the source of truth for waveform, RMS, phasor, and stream details. Per-stream state must remain isolated; consumers must never combine values from different publishers. The v1.4 runtime snapshot boundary copies mutable analyzer collections before atomic publication. See [`docs/architecture/STREAM_RUNTIME.md`](docs/architecture/STREAM_RUNTIME.md) and [`docs/architecture/RUNTIME_SNAPSHOT_AND_REPLAY.md`](docs/architecture/RUNTIME_SNAPSHOT_AND_REPLAY.md).
83+
84+
The first replay reader supports classic PCAP 2.4 with Ethernet link type 1 in little/big-endian microsecond or nanosecond variants. PCAPNG is not yet claimed.
8285

8386
## Build from source
8487

@@ -106,8 +109,8 @@ dotnet run --project .\src\ProcessBus.App.Wpf\ProcessBus.App.Wpf.csproj -c Relea
106109
Create and verify a portable package:
107110

108111
```powershell
109-
.\scripts\publish-windows-portable.ps1 -Version "1.3.0-beta.2"
110-
.\scripts\verify-release-package.ps1 -PackageZip ".\artifacts\release\ProcessBusInsight-v1.3.0-beta.2-win-x64-portable.zip"
112+
.\scripts\publish-windows-portable.ps1 -Version "1.4.0-beta.1"
113+
.\scripts\verify-release-package.ps1 -PackageZip ".\artifacts\release\ProcessBusInsight-v1.4.0-beta.1-win-x64-portable.zip"
111114
```
112115

113116
Run the repository-quality gate:
@@ -122,9 +125,15 @@ Run only the deterministic runtime-stability suite:
122125
dotnet test .\tests\ProcessBus.Tests\ProcessBus.Tests.csproj -c Release --filter "Category=RuntimeStability"
123126
```
124127

128+
Run only the immutable snapshot and PCAP replay suite:
129+
130+
```powershell
131+
dotnet test .\tests\ProcessBus.Tests\ProcessBus.Tests.csproj -c Release --filter "Category=RuntimeArchitecture"
132+
```
133+
125134
## Validation status
126135

127-
The repository includes parser and regression tests, repeated deterministic multi-stream stability evidence, CI build/test evidence, CodeQL analysis, dependency review, release-package verification, and explicit repository-hygiene checks. Public-beta status does **not** imply vendor certification or measurement-grade timing validation.
136+
The repository includes parser and regression tests, repeated deterministic multi-stream stability evidence, immutable runtime/replay evidence, CI build/test evidence, CodeQL analysis, dependency review, release-package verification, and explicit repository-hygiene checks. Public-beta status does **not** imply vendor certification or measurement-grade timing validation.
128137

129138
Before interpreting results, review:
130139

@@ -140,8 +149,9 @@ Before interpreting results, review:
140149
- [`docs/USER_MANUAL.md`](docs/USER_MANUAL.md) — user workflow
141150
- [`docs/TROUBLESHOOTING.md`](docs/TROUBLESHOOTING.md) — capture and interpretation issues
142151
- [`docs/architecture/STREAM_RUNTIME.md`](docs/architecture/STREAM_RUNTIME.md) — selected-stream and snapshot invariants
152+
- [`docs/architecture/RUNTIME_SNAPSHOT_AND_REPLAY.md`](docs/architecture/RUNTIME_SNAPSHOT_AND_REPLAY.md) — immutable generation and PCAP replay design
143153
- [`docs/validation/TESTED_CONFIGURATIONS.md`](docs/validation/TESTED_CONFIGURATIONS.md) — explicitly tested environments
144-
- [`docs/validation/V1.3.0_BETA2_FIELD_EVIDENCE.md`](docs/validation/V1.3.0_BETA2_FIELD_EVIDENCE.md) — maintained live/replay evidence form
154+
- [`docs/validation/V1.3.0_BETA2_FIELD_EVIDENCE.md`](docs/validation/V1.3.0_BETA2_FIELD_EVIDENCE.md) — maintained 60-minute live stability evidence
145155
- [`docs/RELEASE_PACKAGING.md`](docs/RELEASE_PACKAGING.md) — portable packaging design
146156
- [`ROADMAP.md`](ROADMAP.md) — product direction
147157
- [`SECURITY.md`](SECURITY.md) — vulnerability reporting and data-handling policy

0 commit comments

Comments
 (0)