feat: add AR Virtual Relay Lab P0 premium protection workspace - #48
feat: add AR Virtual Relay Lab P0 premium protection workspace#48masarray wants to merge 16 commits into
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 62028d138d
ℹ️ 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".
| _smvHealthy, | ||
| _smvHealthy ? "SMV HEALTHY" : "SMPCNT GAP / STREAM UNTRUSTED"); | ||
|
|
||
| var snapshot = _protectionEngine.Evaluate(frame); |
There was a problem hiding this comment.
Decouple protection evaluation from the WPF dispatcher
Evaluate runs only from a 20 ms DispatcherTimer callback and uses UtcNow to calculate protection elapsed time. If the UI thread stalls or the lab is paused for 500 ms during pickup, the next frame advances the protection timers by that entire gap and may trip immediately; gaps over one second are instead discarded by ProtectionEngine, so identical inputs produce different operation times depending on UI responsiveness. This also contradicts the new PRD's requirement that UI stalls cannot change protection timing. Run protection from an independent bounded measurement loop with sample-derived timestamps.
AGENTS.md reference: AGENTS.md:L15-L19
Useful? React with 👍 / 👎.
| SetLed(PhaseALed, snapshot.PhasePickup ? Indicator.Warning : Indicator.Off); | ||
| SetLed(PhaseBLed, Indicator.Off); | ||
| SetLed(PhaseCLed, Indicator.Off); |
There was a problem hiding this comment.
Preserve the actual picked-up phase
For a frame where only Phase B or Phase C exceeds pickup, ProtectionSnapshot exposes only the aggregate PhasePickup flag, so this code always lights PHASE A and leaves PHASE B/C off. This produces incorrect phase-segregated evidence for non-A-phase experiments; carry per-phase pickup/operate state through the typed snapshot and drive each LED from its corresponding phase.
AGENTS.md reference: AGENTS.md:L181-L186
Useful? React with 👍 / 👎.
| double MaxPhaseCurrent, | ||
| double ResidualCurrent); | ||
|
|
||
| public sealed class ProtectionEngine |
There was a problem hiding this comment.
Move the protection state machine into the reusable stack
The new 50/51 timing, trip-gating, and latch state machine is compiled inside the net8.0-windows WPF executable, forcing its tests and any future CLI, simulation, or subscriber consumer to reference the UI application. This makes the app an alternative protection engine rather than a thin consumer and prevents reuse on non-Windows stack surfaces; place the typed engine contract and implementation in src/ and have the WPF project depend on it.
AGENTS.md reference: AGENTS.md:L68-L71
Useful? React with 👍 / 👎.
| <ComboBoxItem Content="Internal deterministic demo" /> | ||
| <ComboBoxItem Content="Live Npcap subscriber" /> | ||
| <ComboBoxItem Content="PCAP replay" /> |
There was a problem hiding this comment.
Disable source modes until they are implemented
Selecting either "Live Npcap subscriber" or "PCAP replay" has no effect: SourceCombo is never read, and RunButton_Click always starts the same synthetic Timer_Tick frames while presenting healthy SMV and stream metadata. A user attempting a live or replay experiment therefore sees fabricated demo measurements as though the chosen source were active; disable or explicitly label these options as unavailable until the source pipeline is wired.
AGENTS.md reference: AGENTS.md:L15-L16
Useful? React with 👍 / 👎.
| if (!source.Contains("smv.allowsTrip", StringComparison.Ordinal)) | ||
| errors.Add("mandatory SMV trust gate is missing"); |
There was a problem hiding this comment.
Replace token checks with real DSL validation
The supposed mandatory trust gate is accepted merely when the source contains the substring smv.allowsTrip; it can appear in a comment, unused expression, or otherwise malformed input such as { } trip smv.allowsTrip. That input enables staging and reports that syntax, units, bounded runtime, and the gate all passed even though none were analyzed. Until a parser and typed validator exist, this action should report the feature as not implemented rather than presenting unsupported safety validation as successful.
AGENTS.md reference: AGENTS.md:L15-L19
Useful? React with 👍 / 👎.
|
|
||
| private void Stage_Click(object sender, RoutedEventArgs e) | ||
| { | ||
| _algorithms[ElementList.SelectedIndex] = AlgorithmTextBox.Text; |
There was a problem hiding this comment.
Invalidate validation when the source changes
After a source passes validation, editing AlgorithmTextBox does not disable StageButton, and Stage_Click stores the current text rather than the revision that was validated. A user can therefore validate the default algorithm, remove the trust gate or insert forbidden content, and immediately stage the unvalidated revision. Reset validation on every text change or bind staging to an immutable validated revision/hash.
AGENTS.md reference: AGENTS.md:L15-L19
Useful? React with 👍 / 👎.
Summary
Introduces the P0 execution baseline for AR Virtual Relay Lab, a vendor-neutral IEC 61850 Sampled Values protection laboratory.
Delivered
docs/VIRTUAL_RELAY_LAB_PRD.md;ARIEC61850.sln.Verification
The new tests cover normal load security, 50P definite-time trip, SMV trust blocking, 50N operation, 51P inverse accumulation and trip-latch reset.
Safety boundary
This P0 build produces virtual trip indications only. It adds no active GOOSE, MMS control or physical output path.
Next increment
P1 will replace deterministic demo frames with the real ArSubsv/ARIEC61850 subscriber pipeline: Npcap capture, PCAP replay, SCL binding, channel mapping, scaling, circular sample buffers and evidence events.