Skip to content

M2.17-D Field convergence: GoCB passive evidence, SGCB initial status, RCB/Read correctness - #606

Closed
masarray wants to merge 11 commits into
feat/m217c-bounded-priority-live-hydration-20261016from
fix/m217d-bcu-goose-sgcb-rcb-datamodel-20261016
Closed

masarray wants to merge 11 commits into
feat/m217c-bounded-priority-live-hydration-20261016from
fix/m217d-bcu-goose-sgcb-rcb-datamodel-20261016

Conversation

@masarray

Copy link
Copy Markdown
Owner

M2.17-D / BCUGE field-feedback correctness slice — stacked draft on #605

This patch follows the physical operator screenshots. It deliberately fixes documented seams, not an entire UI repaint or a fabricated "all data complete" claim.

Root causes and repairs

  1. GOOSE: real subscriber frame invisible in GoCB Browser. The existing IedBrowserGooseInspection.Select rejected every wire frame when the online GoCB discovery did not disclose its DataSet reference. Permit a single exact received GoCbRef (matching declared GoID/AppID/confRev when available) to supply its ACTUAL PDU DataSet reference. A conflicting known DataSet, different IED model, APPID, rev, or ambiguous duplicate still fails closed. Reuse the existing GOOSE Sniff subscriber via a visible Subscribe GOOSE action; never start a second reader/decoder/cache. For missing or conflicting FCDA directories, surface original allData positions as explicitly Wire entry #N (unbound), never name them as model FCDA or borrow sibling FC. Do not infer MMS GoEna from passive reception.
  2. SGCB: no initial NumOfSG/ActSG/LActTm. The M2.17-C priority plan only scanned LN DO attributes. The verified live SGCB attribute inventory lives elsewhere; include only those 3 read-only fields, with domain/FC/inventory proof, under the SAME sequential 32-target / 10-second hydration budget. Never read EditSG/CnfEdit, select/edit groups or write a setting. Historical SCL-only declarations remain non-authoritative.
  3. Data Model: Read appeared ineffective. Expanding a DO silently changed the later LN Read target to that last-clicked DO; the screenshot showed a successful 3/4 sweep while other DOs remained Not read. Read now means the whole selected LN and Read All still means the whole model. Clicking/expanding rows is navigation, not a hidden acquisition-scope change. Existing read results are still fenced by association/catalog.
  4. Report flag collapsibility regression. Trigger/optional flag rows now live beneath Control Block attributes instead of becoming separate Section siblings. The existing engine flag codec and shared section projection remain authoritative; no bit decoder added.
  5. Report RCB activity indicator stale. Runtime RCB activation completes asynchronously after IsMonitoring changes. Rebuild existing glyphs only when the actual activated RCB identity set changes. Explicit read-only RCB checks are additionally fenced against association/schema swap. RCB use by another client still requires a real read-only status check, never inference from name or missing report frames.
  6. Files indentation. Add a small inner padding on the Filename icon/text cell only; no new WPF cards, icons or file transfer behavior.

Tests and safety

Seven added focused regressions covering selected physical-style GoCB + subscriber allData, missing directory, duplicate/conflicting frame rejection, bounded exact SGCB read priorities and unauthorized FC rejection, report-control collapse hierarchy, existing subscriber use, RCB association fences and file indent. No engine re-pin, no native library change, no protocol replacement, no GOOSE emission, no MMS writes, no auto Read All.

What this does NOT claim

  • Remote RCB occupancy needs on-device check; a passive Report is not proof of remote owner.
  • Unread SG leaf values and analog DataSet values still require real model-proven Read/Report evidence; missing or BER-unprojectable attributes are not assigned default zero.
  • No physical acceptance claim without a repeat capture and per-row failure diagnostics from the same IED.

Keep draft; merge/promotion only after exact-SHA CI and physical interoperability review.

Copy link
Copy Markdown
Owner Author

Reconciliation finding (2026-10-26): KEEP OPEN — unproven unique regression delta. The original #606 source 9474a5ca07e1d245ce0020d873ff9445bc19aa78 contains tests/ARSAS.Tests/M217DFieldEvidenceConvergenceTests.cs (blob 9df525047ac1186ed822a7f2a0cd0f86f811a4a9, 7 test cases) that is absent by exact path from current RC 817c3910e8223fa2ac531a4426ada5d2d4bbbe50 (recursive Git tree checked). Cases cover exact GoCB wire identity, wrong-publisher rejection, ordered real PDU/unbound slots, SGCB live evidence/fail-closed paths, report-control section nesting, and passive subscribe + RCB association fencing. Absence of the file is not yet proof that behavior regressed; equivalents may exist under other classes. Do not close this PR before mapping every assertion to live RC regression tests or porting distinct coverage. Preserve branch and field evidence; do not invent physical acceptance or mutate the currently trial-pinned engine. See repository audit checkpoint branch audit/arsas-pr-issue-reconciliation-20261026. Next: semantic assertion matrix old-to-current, targeted test restoration on an isolated branch if coverage is missing, then existing required CI and physical gate review.

Copy link
Copy Markdown
Owner Author

Reconciliation D1 — 7-test historical coverage map (2026-10-26)

Disposition: D — KEEP OPEN until the two incomplete assertions are resolved. Old test blob 9df525047ac1186ed822a7f2a0cd0f86f811a4a9 is absent from RC 817c3910e8223fa2ac531a4426ada5d2d4bbbe50; original branch and full file remain intact. The PR is diverged from RC (ahead 1236, behind 11 from old HEAD → RC), so ancestry is NOT sufficient.

Historical assertion Current canonical candidate (RC) Disposition
ExactGoCbWireIdentityRecoversLiveMetadataWithoutMmsDataSetInventory IedBrowserGooseInspectionTests.FullyQualifiedWireGoCbCanBeObservedWithoutMmsDataSetDirectory plus BrowserHasUnboundWireAllDataFallbackWithoutRewritingLedger Partial: GoCB identity preserved, historical raw slot validation method removed
NeverSelectWrongPublisherAmbiguousFrameOrConflictingConfiguration IedBrowserGooseInspectionTests.ExactCanonicalControlIdentityAndOnePublisherRequired; Select rejects ambiguous duplicate publishers, wrong AppID/ConfRev, wrong IED Covered for specified identity conditions
UnboundWireSlotsRequireCompleteOrderedRealPdu VerifiedMembers validates bound directory slots; raw unbound view in MainWindow.IedBrowser.cs:1706-1758 displays frameView.Leaves with min(128) and no local WireDataSetEntryCount==Leaves.Count, contiguous unique index or missing-value check GAP/needs tracing: validate guarantee at the subscriber decoder boundary or add fail-closed raw unbound slot admission plus focused regression. Do not restore removed OrderedWireEntries blindly
SGCBStatusIsHydratedFromExactLiveInventoryWithoutWritingEditGroup IedBrowserControlStateEvidenceTests.FullLiveInitialHydrationIncludesOnlyVerifiedReadOnlySgcbStatus, SgcbReadsOnlyExactInventoryDeclaredReadOnlyMmsLeaves Covered incl bounded 3→2→1 and no EditSG/CnfEdit
SGCBFailsClosedForSclOnlyUnknownFcOrWrongDomain IedBrowserControlStateEvidenceTests.UnverifiedOrConflictingSgcbNeverTriggersProbe, InitialSgcbPlanRejectsSclOnlyAndAmbiguousInventory Partial: SCL/wrong FC covered; verify wrong-domain control block relative to model LogicalDevices (not just self-consistent block identity)
TriggerAndOptionalFlagsAreChildrenOfReportControlSection M217DGooseRcbFilesUxRegressionTests.ReportFlagsStayInsideControlBlockExpandableSection Covered
PassiveSubscribeAndRcbGlyphReuseExistingRuntimeAndAreAssociationFenced IedBrowserGooseInspectionTests.BrowserSubscribeIsInlineAndSharesOriginalNpcapStartStop; present IedBrowserGooseSubscribe_Click calls StartGooseSubscriber_Click(sender,e), not the obsolete OpenIedGooseSubscriber(device). Live association fences are present in read/UI code Updated subscriber UX covered; check async model/association epoch attribution separately; old source-text assertion is now intentionally obsolete

Safety: no code or test was ported without checking new APIs; raw allData is always labeled unbound and must never be promoted to FCDA or MMS ledger. Never merge the historical file as-is (obsolete OrderedWireEntries and OpenIedGooseSubscriber expectations).

Follow-up: ask canonical IED Browser/GOOSE owner to trace decoder invariants for wire count/order/missing sentinel and add minimal test-only cases for any true missing behavior. Likewise prove/fence wrong-domain SGCB (a syntactically valid block from another model domain must not silently become current association authority). Keep #606 open pending focused tests and required CI; no physical GOOSE/safety acceptance implied.

Copy link
Copy Markdown
Owner Author

Reconciliation D3 — focused rescue is now a separate current-RC draft PR

Disposition: KEEP historical #606 OPEN (no blind cherry-pick / no ancestry-only closure). The two unique current-tree gaps identified in D1 7-method matrix now have a narrowly scoped corrective candidate: #753, branch safety/m217d-raw-goose-sgcb-admission-20261026, head d0fbb5c2ae9f69f56badbba9bef5e15d66a78dc7, base protected RC 817c3910e8223fa2ac531a4426ada5d2d4bbbe50.

Copy link
Copy Markdown
Owner Author

D5 source-test continuity: #606 stays OPEN until current RC integration and seven-case adjudication

Existing historical head: 9474a5ca07e1d245ce0020d873ff9445bc19aa78; old unique test blob 9df525047ac1186ed822a7f2a0cd0f86f811a4a9. Legacy file contains exactly 7 [Fact] methods. Old source API/text assertions must not be blindly restored because Browser GOOSE subscriber and RCB UI have evolved.

Real current-tree rescue: draft #753 has progressed beyond D3: new exact head 410a2fd3c8757f9c9cac46e2df6cb4ce047585b7, ancestor RC base 817c3910e8223fa2ac531a4426ada5d2d4bbbe50, ahead6/behind0, 6 changed files. Test-only added tests/ARSAS.Tests/M217DCurrentTreeEvidenceContinuityTests.cs:

  • ExactWireGoCbCanBeReadUnboundWithoutAnMmsDataSetInventory — full GoCB identity, no MMS DatSet inventory or publisher label, positive ordered unbound PDU, no FCDA/FC claims, negative wrong/empty GoCB, ambiguous dual publisher, wrong APPID.
  • ExactLiveSgcbInitialReadIsBoundedReadOnlyAndSkipsObservedFields — exact 3 read-only SGCB status leaves, excludes EditSG/CnfEdit; association-observed ActSG reduces 3→2; maxTargets1 bounded; offline suppresses read.
  • UnverifiedSclOrWrongFcNeverBecomesAnInitialSgcbRead — reject SCL-only, FC≠SP, zero budget. Existing new M2.17-D safety: reject incomplete unbound GOOSE and foreign-domain SGCB/GoCB reads #753 tests separately reject foreign model-domain SGCB/GoCB and malformed/duplicate/missing unbound GOOSE slots.

Original seven-assertion disposition matrix:

  1. ExactGoCbWireIdentityRecoversLiveMetadataWithoutMmsDataSetInventory → new exact no-MMS-inventory GOOSE regression above (real PDU identity, unbound entries).
  2. NeverSelectWrongPublisherAmbiguousFrameOrConflictingConfiguration → current IedBrowserGooseInspectionTests.ExactCanonicalControlIdentityAndOnePublisherRequired + new wrong/ambiguous GoCB/APPID case.
  3. UnboundWireSlotsRequireCompleteOrderedRealPdu → new OrderedUnboundWireEntries current-tree implementation + UnboundAllDataRejectsIncompleteDuplicateOrMissingRealWireSlots + callsite gate. This is actual P0 source fix, not inherited old test text.
  4. SGCBStatusIsHydratedFromExactLiveInventoryWithoutWritingEditGroup → new 3→2/limit/offline test above + existing SgcbReadsOnlyExactInventoryDeclaredReadOnlyMmsLeaves.
  5. SGCBFailsClosedForSclOnlyUnknownFcOrWrongDomain → new SCL-only/FC/zero-budget + current UnverifiedOrConflictingSgcbNeverTriggersProbe + M2.17-D safety: reject incomplete unbound GOOSE and foreign-domain SGCB/GoCB reads #753 InitialControlStateHydrationRejectsForeignMmsDomain.
  6. TriggerAndOptionalFlagsAreChildrenOfReportControlSection → current IedBrowserPresentation uses explicit section headings for TrgOps/OptFlds but IedBrowserDetailSectionLayout.Attach attaches those sections under the RCB Control Block attributes collapse, preserving structural operator grouping. The old literal raw-projection assertion is intentionally NOT equivalent, since the GUI now has nested visual grouping; requires acceptance against current GUI/RCB tests before declaring full parity.
  7. PassiveSubscribeAndRcbGlyphReuseExistingRuntimeAndAreAssociationFenced → current Browser handler calls shared StartGooseSubscriber_Click(sender,e) in-place (not obsolete OpenIedGooseSubscriber), retains Npcap decoder, per-session IedBrowserRcbCheckLease.IsCurrent association/model fence (replaces string snapshot checks). Current RCB glyph/layout differs from 2026-10-16 text assertion; UI acceptance remains independent.

CI truth: previous 5-file #753 exact head d0fbb5c2ae9f69f56badbba9bef5e15d66a78dc7 passed full Windows application/native/portable smoke. The NEW 6-file head 410a2fd3c8757f9c9cac46e2df6cb4ce047585b7 has its own automatically triggered exact-head CI Windows run 40299449108 and SCL run 40299449103, not yet accepted as successful at comment creation. Do not reuse green older head as a pass claim for the new test file.

Safety: No #606 source branch mutation, no main, no engine lock, no MMS Write/Operate, no public release. Keep #606 OPEN until #753 exact-head CI, owner/GUI parity review, approved RC integration, and physical GOOSE/SGCB validation gates as applicable.

Copy link
Copy Markdown
Owner Author

D6 acceptance update — #753 current-tree rescue exact-head Windows+SCL CI fully green, #606 still OPEN

The current canonical six-file recovery #753 410a2fd3c8757f9c9cac46e2df6cb4ce047585b7 is now independently confirmed successful on Windows job #121493442949 (all 36 steps, Build solution, app tests including new GoCB/SGCB current-tree assertions, pinned native CTest/portable EXE smoke/sealing) and SCL job #121493442770. The exact 7-method old→current mapping remains in prior review. Full checkpoint D6.

Disposition: KEEP #606 OPEN, historical 7-test source preserved, no blind cherry-pick. #753 remains DRAFT / UNMERGED until RC owner accepts deliberately changed visual RCB flag nesting/section default, shared GOOSE subscriber boundary and exact-source #753 integration. Physical IED GOOSE/SGCB FAT, R7/R10 promotion and command #615 remain separate. Success on draft code is not synonymous with accepted release, nor proof of physical wire transmission.

Copy link
Copy Markdown
Owner Author

D28 legacy candidate archived, not merged. Per the operator's explicit instruction, the latest accepted ARSAS working evidence is the baseline; no new hardware/packet capture cycle is required for cleaning up outdated PRs. Historical candidate 9474a5ca07e1d245ce0020d873ff9445bc19aa78 is withdrawn from the integration queue, with source/review history intact. Closing it does not assert its unmerged source fixes shipped, does not authorize weakening protocol safety, and does not modify main, stable, RC or engine pins.

@masarray masarray closed this Oct 27, 2026
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