Skip to content

FAT: smart IEC 61850 binding + COMTRADE/time-sync evidence - #140

Merged
masarray merged 22 commits into
mainfrom
agent/fat-smart-evidence
Aug 12, 2026
Merged

FAT: smart IEC 61850 binding + COMTRADE/time-sync evidence#140
masarray merged 22 commits into
mainfrom
agent/fat-smart-evidence

Conversation

@masarray

@masarray masarray commented Aug 12, 2026

Copy link
Copy Markdown
Owner

Summary

  • make FAT IEC 61850 signal resolution tolerant of safe MMS/SCL spelling differences without fuzzy guessing
  • normalize MMS functional-constraint tokens such as $ST$ / $MX$, IED-prefixed domains, DIGSI Application wrappers, and verified functional-group/LN display hierarchy
  • keep ambiguous matches blocked instead of guessing
  • arm explicit time-sync status signals automatically during FAT monitoring and capture device-level time-sync evidence with timestamp fallback
  • treat successful IEC 61850 FileDirectory discovery of a supported remote COMTRADE/fault record as IED-level File Service FAT PASS; downloading the file is not required for this browse-service evidence
  • select the latest remote fault record by relay LastModifiedUtc and persist its exact COMTRADE filename(s), remote path, completeness, relay modified time, source, file count, and known size per IED
  • append remote COMTRADE discovery to the existing tamper-evident .evidence.jsonl chain and retain stronger SHA-256 local-artifact evidence when the operator also downloads a record
  • show File Service PASS and latest remote COMTRADE filename(s) in the native PDF / print preview and portable handover HTML report
  • preserve supplemental evidence per IED and across FAT workspace restart / handover restore
  • add regression coverage for Siemens/MiCOM/Reyrolle-style references, latest remote COMTRADE selection/reporting, and COMTRADE evidence persistence

Safety / behavior

  • no fuzzy or Levenshtein signal matching
  • only the unique best canonical IEC 61850 match is accepted; equal candidates remain ambiguous
  • time-sync fallback records an observation but does not falsely claim synchronized state
  • File Service PASS means the IED successfully returned a supported remote fault-record entry through IEC 61850 FileDirectory; it does not claim that FileOpen / FileRead / FileClose succeeded
  • COMTRADE download remains optional deeper verification and diagnostics; skipped or failed download does not erase a valid remote FileDirectory PASS
  • downloaded local COMTRADE remains separately hashable/journalable evidence when available

Validation note

CI validates build, regression, report, persistence, packaging, and application smoke paths. Live MMS association and actual relay FileOpen / FileRead transfer still require an IED/network test at the FAT bench before claiming physical file-download interoperability.

@masarray
masarray marked this pull request as ready for review August 12, 2026 10:48

Copy link
Copy Markdown
Owner Author

Validation complete on head 8c6d5e95218074feb9bddd89e8bd621a2af2db48:

  • Validate IO List Testing — focused FAT/IO build + regression tests passed (run 31588676515)
  • Build ARSAS — full solution build + application regression tests passed (run 31588676769)
  • ✅ portable x64 publish + smoke test passed
  • ✅ matcher coverage includes MMS FC-token normalization, IED/Application wrappers, safe implicit value leaves, and ambiguity rejection
  • ✅ COMTRADE/time-sync evidence is journaled per IED and therefore remains independent from panel/test-point scope

Remaining acceptance item is intentionally hardware-only: run the branch against the target FAT relay/network to verify the actual MMS association, report acquisition and IEC 61850 fault-record transfer for the installed IED firmware.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8c6d5e9521

ℹ️ 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".

Comment on lines +55 to +59
public string EvidenceKind { get; init; } = string.Empty;
public string ArtifactName { get; init; } = string.Empty;
public string ArtifactPath { get; init; } = string.Empty;
public string ArtifactSha256 { get; init; } = string.Empty;
public long ArtifactBytes { get; init; }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve the hash input for existing evidence journals

Adding these serialized properties invalidates every journal created by an earlier release: IoTestEvidenceJournal.Verify deserializes each old entry and then reserializes it to recompute the hash, at which point these initialized empty/default fields are emitted even though they were absent from the original hash input. Consequently, opening or exporting a workspace with pre-upgrade evidence reports a hash mismatch; the verifier needs a versioned/legacy hash representation rather than relying on defaults.

Useful? React with 👍 / 👎.

Comment on lines +116 to +120
var syncSignal = IoFatSupplementalEvidenceService.FindTimeSyncSignal(device);
if (syncSignal != null)
{
for (var attempt = 0; attempt < 8 && !HasLiveValue(syncSignal.Value); attempt++)
await Task.Delay(175).ConfigureAwait(true);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Wait for the monitored time-sync point instead of the signal

On the saved-model fast-reconnect path, cached SignalDefinition instances start with Value = "-", while monitoring publishes live values into device.Points and does not copy them back into the signal. This loop therefore waits on a value that never changes and CaptureTimeSync subsequently reads the same stale signal, recording PENDING even when the newly armed time-sync point has a valid live status; resolve and inspect the corresponding monitored point instead.

Useful? React with 👍 / 👎.

Comment on lines +49 to +55
return device.Signals
.Where(signal => !signal.IsControlSignal && !string.IsNullOrWhiteSpace(signal.ObjectReference))
.Select(signal => new { Signal = signal, Score = TimeSyncScore(signal) })
.Where(item => item.Score > 0)
.OrderByDescending(item => item.Score)
.ThenBy(item => item.Signal.ObjectReference, StringComparer.OrdinalIgnoreCase)
.Select(item => item.Signal)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restrict time-sync selection to unique status signals

When an IED exposes both a setting such as TimeSyncEnable.setVal and a synchronization-status object, this ranking can select the setting solely because TimeSync scores higher, without checking ST/MX runtime eligibility or requiring a unique best status candidate. CaptureTimeSync then maps values such as on or active to PASS, so configuration enablement can be journaled as proof that the clock is synchronized; filter to readable status leaves and withhold automatic evidence when the best match is ambiguous.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Remote COMTRADE FAT semantics are now implemented and validated at head 13883e1081b4049623bc21c68191b015b9f4aeec.

  • IEC 61850 FileDirectory returning a supported remote COMTRADE/fault record is IED-level File Service PASS; download is optional and not a FAT gate.
  • ARSAS selects the latest record by relay LastModifiedUtc, persists its exact filename(s)/path/completeness/timestamps per IED, and journals the discovery as tamper-evident supplemental evidence.
  • Native PDF / print preview and portable handover HTML show the latest remote COMTRADE filename(s).
  • A regression initially exposed that the workbook bootstrap restore path ignored IED-level supplemental fields. That restore path is now fixed and covered by a restart/persistence test.
  • Validate IO List Testing #129: green.
  • Build ARSAS #947: green through full regression suite, portable x64 publish, and portable EXE smoke test.

Physical IED bench validation is still required before claiming actual FileOpen / FileRead download interoperability; this PR intentionally does not infer download success from FileDirectory browse success.

@masarray
masarray merged commit 430aaf8 into main Aug 12, 2026
3 checks passed
masarray added a commit that referenced this pull request Aug 13, 2026
Enable independent per-IED FAT connection, discovery, and report monitoring while preserving single-active, device-filtered evidence journaling. Replace the global preparation lock with per-IED state, target-scoped BindIed refreshes, independent Connect/Prepare/Refresh UX and card progress, and continuation-safe connection scope. Keep P0 matching fail-closed and preserve completed evidence. Validated by IO #140, SV #176, full 154-test Build ARSAS #972, portable publish, and smoke test.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant