Add auditable Sampled Values evidence bundles - #109
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6407ece174
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| for (var sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++) | ||
| { | ||
| builder.Append(sampleIndex.ToString(CultureInfo.InvariantCulture)); | ||
| var smpCnt = (snapshot.FirstSampleCount + sampleIndex) % wrap; |
There was a problem hiding this comment.
Preserve the actual captured smpCnt values in the CSV
When FirstSampleCount is outside the two-cycle window size, this immediately writes a false counter value—for example, a snapshot starting at 1000 with 80 samples/cycle emits 40 because it takes modulo 160, contradicting the manifest's firstSampleCount. It also invents a continuous sequence for REVIEW captures containing gaps, duplicates, out-of-order samples, or restarts. Since the snapshot currently retains only the first and last counters, preserve each ASDU's actual smpCnt during capture and export that sequence alongside its raw sample.
Useful? React with 👍 / 👎.
| private void RefreshEvidenceBundleButton() | ||
| { | ||
| if (_exportEvidenceButton is not null) | ||
| _exportEvidenceButton.IsEnabled = _snapshot is not null && !CancelButton.IsEnabled; |
There was a problem hiding this comment.
Refresh export availability after capture ends
On the normal successful-capture path, ApplySnapshot changes SnapshotChannels before Capture_Click reaches its finally and calls SetCaptureState(false), so every collection-triggered refresh sees CancelButton.IsEnabled == true and leaves this button disabled. The final transition that disables Cancel does not call RefreshEvidenceBundleButton, and there is no subsequent collection change, so an accepted snapshot cannot be exported through the new UI.
Useful? React with 👍 / 👎.
| capture = new | ||
| { | ||
| snapshot.NominalFrequencyHz, |
There was a problem hiding this comment.
Record the capture timestamps in the manifest
When a snapshot is exported later or exported more than once, exportedAtUtc identifies only when the ZIP was written; the available SmvSnapshotResult.StartedAt and CompletedAt values are omitted from the capture evidence. Consequently, a reviewer cannot establish when the represented network observation occurred or distinguish otherwise identical captures, which undermines the bundle's audit trail.
Useful? React with 👍 / 👎.
|
Closing this PR as superseded by #108. Both implement the same stacked P1 Sampled Values evidence-bundle scope on top of #107, but #108 has the broader audited bundle, dedicated validation workflow, deterministic regression coverage, and all review findings resolved. This PR still has unresolved correctness findings around exported smpCnt evidence, export-button state, and capture timestamps. Keeping one canonical P1 path avoids duplicate exporters and overlapping edits to the SMV window, project metadata, tests, and changelog. |
Purpose
Implement ARSAS P1 as a single auditable Sampled Values Evidence Bundle that can be stored, transferred, compared, and reviewed after a bounded passive capture.
Evidence bundle
The SMV Snapshot Viewer now exports one ZIP containing:
waveform.png— rendered static raw-lane waveformsamples.csv— sample index, reconstructed displayed smpCnt sequence, and every plotted raw lanemanifest.json— schema, PASS/REVIEW verdict, stream identity, capture evidence, channel metadata, and explicit evidence boundarydiagnostics.txt— continuity counts, timebase, payload shape, parser diagnostics, and unresolved-semantic boundarySHA256SUMS.txt— SHA-256 for every evidence entryThe completed ZIP also receives a bundle-level SHA-256 shown to the operator.
Provenance
engines/ARIEC61850.lock.jsonEngine commit remains
0f8453182957900bc6d91287fb8177c8d9762188.Safety and UX
SmvSnapshotResult.IsCleanProofRegression validation
Adds an application test that creates a real ZIP, opens it, and verifies:
Stack boundary
This PR is intentionally based on P0 branch
agent/p0-hardening-1-6-19/ PR #107. It contains only the P1 delta. Stable public release remains 1.6.18.