Skip to content

Add native xRegistry events and distinct Resource versions - #4396

Merged
marcschier merged 41 commits into
OPCFoundation:masterfrom
marcschier:xregistry-events
Sep 8, 2026
Merged

Add native xRegistry events and distinct Resource versions#4396
marcschier merged 41 commits into
OPCFoundation:masterfrom
marcschier:xregistry-events

Conversation

@marcschier

@marcschier marcschier commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • support the xRegistry 0.6.0 distinct Resource/Version hierarchy:
    Registry -> Group -> Resource -> Versions -> Version
  • instantiate stable logical Resource nodes separately from exact Version nodes
    while preserving existing Version NodeIds
  • delegate logical Resource FileType operations and Version-view metadata to the
    selected default Version with handle pinning and shared writer reservations
  • make Resource and Version delete behavior role-stable and use MetaEpoch /
    Epoch respectively
  • use stable Resource SourceNodes, exact Version SourceNodes and the
    Server -> Registry -> Group -> Resource -> Version notifier chain
  • keep a model-metadata-gated client fallback for 0.5 flat Servers; 0.6 Servers
    expose no legacy aliases
  • target HasWoTProjection at the real stable logical Resource node
  • use AsyncCustomNodeManager for the registration, fast-path, and federation managers,
    with awaited lifecycle, node mutations, event delivery, and cleanup
  • handle startup rollback, reentrant deletion callbacks, undisclosed file handles,
    and retryable cleanup without blocking unrelated file operations

Authoritative dependencies

Review feedback

  • keep the WoT Connectivity information-model designation at 1.1; draft revisions update the publication date without changing the model version

  • eliminate all 198 unique CA1861 diagnostics across 54 files and remove seven obsolete project suppressions

  • fix the analyzer-clean touched-path CA1307 and the hierarchy follow-up CA1846/CA1851 diagnostics without dropping legacy-TFM compatibility

  • recover the reconcile queue after callback faults/cancellation and continue accepted pending changes

  • remove migration guidance for the xRegistry managers, which are new in 2.0

Compatibility

  • public WoT Connectivity model designation remains 1.1
  • generated event-record ABI, constructors, options, NodeIds, and stored documents remain compatible
  • the generic xRegistry managers are new in 2.0 and implement IAsyncNodeManager;
    use IAsyncNodeManagerFactory and the async lifecycle hooks (see docs\XRegistry.md)
  • persistence schema and document blobs remain compatible unless noted below

Validation

  • merge validation at 980422f76 with upstream e8bec27d5: 454 targeted WoT/materialization/model/registry cases and all 327 XRegistry cases passed on both net10.0 and net48; all 29 net10 aggregation sample cases passed
  • feedback regressions at 308e8ba74: 55 targeted queue and live registry event/projection/lifecycle cases passed on each of net10.0 and net48
  • prior CI: all 266 checks passed at 6489a0908; the unchanged Ubuntu Core certificate-counter test and dependent jobs passed on the one-time retry (run 34117304035, attempt 2)
  • Opc.Ua.XRegistry.Tests — 327 passed on net10.0 and net48 for migration commit 32c914aaf
  • Opc.Ua.WotCon.Tests net10.0 — 1348 passed
  • Opc.Ua.WotCon.Bindings.Tests net10.0 — 683 passed
  • Opc.Ua.SourceGeneration.Core.Tests net10.0 — 3807 passed, 8 skipped
  • Opc.Ua.SourceGeneration.Tests net10.0 — 145 passed
  • Opc.Ua.SourceGeneration.Stack.Tests net10.0 — 94 passed
  • affected XRegistry and WoT client/server projects build successfully
  • xRegistry NodeSet is byte-identical to the companion artifact
  • repository-wide CA1861 inventory — 198 unique diagnostics across 54 files reduced to zero
  • targeted changed-fixture validation — 1,098 passed, 3 skipped, 0 failed
  • constrained full UA.slnx net10.0 Release build — CA1861 = 0
  • Opc.Ua.XRegistry.Client net472 and netstandard2.1 builds — 0 warnings, 0 errors
  • independent shared-array safety review — no significant issues
  • git diff --check

The final review regressions cover concurrent reconcile/open, synthetic logical
handle collisions across default switches, cross-session Close isolation,
shared writer reservations, logical FileType property/change propagation,
logical Labels delegation, role-fixed deletion, event sources, model-version
gating, and stable HasWoTProjection targets.

The companion specification and protocol binding are reviewed in the linked PRs above.

Implement optional native event publication, projection reconciliation diffs, generated event decoding, model updates, documentation, and integration coverage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 5c79a1ed-6dab-4522-a9fc-6548caa78ad5
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 5c79a1ed-6dab-4522-a9fc-6548caa78ad5
Separate logical new-Version uploads from concrete Version replacement, keep defaults sticky, persist and validate per Version, and retain IWotRegistryService-only compatibility.

Queue immutable registry transitions without replaying stale address-space generations, migrate file manifests to schema 4, and preserve standard UriString event-record ABI while retaining typed xRegistry SourceUrl.

Root cause: projected closes always requested a default switch, and queued reconciliation recaptured or replayed the latest snapshot instead of processing each supplied transition safely.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 5c79a1ed-6dab-4522-a9fc-6548caa78ad5
Protect active, default, and incoming Versions during retention; persist document metadata per Version; fill contentless placeholders in place; make queued transitions the sole event emitter; and preserve existing UriString record ABI outside xRegistry SourceUrl.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 5c79a1ed-6dab-4522-a9fc-6548caa78ad5
Return exact upload node/version pairs, atomically claim contentless placeholders with safe legacy fallback, and preserve legacy projected WoT metadata.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 5c79a1ed-6dab-4522-a9fc-6548caa78ad5
Comment thread docs/WoTConnectivity.md Outdated
Comment thread tests/Opc.Ua.WotCon.Tests/Registry/FileWotRegistryStoreTests.cs Outdated
@marcschier marcschier changed the title Add native xRegistry events and version semantics Add dual-plane xRegistry operations and native events Sep 3, 2026
@marcschier marcschier changed the title Add dual-plane xRegistry operations and native events Add native xRegistry events and version semantics Sep 4, 2026
marcschier and others added 20 commits September 4, 2026 11:49
Use cross-framework dictionary and null guards, complete the generated event-reader test stubs, seed event and companion namespaces in isolated harnesses, and explicitly select uploaded WoT versions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b605797f-a97a-4cd0-8f12-016d33c2fd88
Replace DateTime.UnixEpoch with a shared UTC epoch value in the WoT registry model and projection tests so net472, net48, and netstandard2.0 builds compile.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b605797f-a97a-4cd0-8f12-016d33c2fd88
Use generic TaskCompletionSource and TryGetValue in the new WotCon tests so the full solution builds on net472, net48, and netstandard2.0.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b605797f-a97a-4cd0-8f12-016d33c2fd88
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 7ef369a5-2307-4f71-8a11-15af0e72f240
Route projected Delete calls from the current default Version to logical Resource deletion while preserving exact Version deletion for non-default nodes. Emit deprecated-on-create events, complete default-switch Changed fields, and omit absent WoT content attributes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7ef369a5-2307-4f71-8a11-15af0e72f240
Honor metadata and default changes for identical-content upserts, trim structural Version creation, preserve explicit xRegistry Version IDs, and keep label changes projection-only.

Add focused service, persistence, model, and live-client regression coverage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 7ef369a5-2307-4f71-8a11-15af0e72f240
Move the repeated expected subject array to static test data to satisfy CA1861 across all target frameworks.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b605797f-a97a-4cd0-8f12-016d33c2fd88
Carry Resource Name and Description through event snapshots and report their canonical Changed names with Resource Meta epochs. Emit GroupDeprecated when a Group is already deprecated at creation time.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7ef369a5-2307-4f71-8a11-15af0e72f240
Defer committed-Version eviction until upload close, preserve metadata-only materialization state, harden Version sequencing and copy invariants, and add atomic projected deletion.

Add focused retention, epoch, persistence, concurrency, and client regression coverage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 7ef369a5-2307-4f71-8a11-15af0e72f240
Delegate versioned projected deletes to one atomic strategy operation backed by IWotVersionedRegistryService.DeleteProjectedEntityAsync. Remove projection snapshot role prechecks and update tests to prove role and epoch resolution occur only at the service seam.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7ef369a5-2307-4f71-8a11-15af0e72f240
Remove the unused exact-Version delete operation from the projection strategy while preserving the public registry operation. Update the placeholder default-switch regression to use one committed Version plus one pending Version and verify absent content metadata is not invented.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7ef369a5-2307-4f71-8a11-15af0e72f240
Reuse abandoned placeholders without evicting committed content, make close-time retention and deletion role-safe, and reject Version incarnation ABA writes.

Preserve legacy persisted ids, desired-version materialization semantics, and consistent client-facing errors with regression coverage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 7ef369a5-2307-4f71-8a11-15af0e72f240
Require callers to provide their observed logical-Resource role and reject role changes atomically before applying Resource or Version epoch checks.

Add regressions for concurrent role switches, stable role deletion, and wrong role or epoch combinations.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 7ef369a5-2307-4f71-8a11-15af0e72f240
Pass the caller-observed logical Resource role from the projected node BrowseName into the atomic registry delete seam. Reject stale projected roles at the service boundary and cover stable, stale, and reconciled role transitions without pre-delete snapshot capture.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7ef369a5-2307-4f71-8a11-15af0e72f240
Derive the caller-observed projected delete role from the logical Resource XID mapping instead of BrowseName, avoiding collisions when a non-default VersionId equals its ResourceId. Add engine and live-server regressions for exact Version and logical Resource deletion.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7ef369a5-2307-4f71-8a11-15af0e72f240
Use stable Version incarnation IDs across immutable copies and write handles, rejecting stale delete/recreate closes while allowing benign metadata and projection updates.

Harden pending-aware Version deletion and exact updates of persisted legacy IDs, with lifecycle, persistence, and immediate-writer regressions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 7ef369a5-2307-4f71-8a11-15af0e72f240
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b605797f-a97a-4cd0-8f12-016d33c2fd88
Integrate the WoT Binding 1.1 conformance update while preserving the xRegistry 0.5 event model and reconciling policy-driven Resource deletion with atomic Version-aware projection semantics.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b605797f-a97a-4cd0-8f12-016d33c2fd88
Copy authoritative NodeSet2.xml and NodeIds.csv from the companion
spec-drafts repo. The xRegistry model adds ResourceVersionsType (63025)
with instance declarations ResourceVersionsType_Version (63589) and
ResourceType_Versions (63590). The WoT-Connectivity model adds
ThingDescriptionVersionsType (64015) and ThingModelVersionsType (64016)
with corresponding instance declarations.

Suppress CS0108 in Opc.Ua.WotCon.csproj for the source-generated
AddVersion_Placeholder method hiding in domain VersionsType subtypes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: e716d455-8397-4d22-9c5a-398847ab7317
In versioned mode (IXRegistryVersionedProjectionStrategy), the
projection engine now creates a three-level hierarchy:
  Group -> LogicalResource -> VersionsFolder -> Version

- Logical Resource: stable NodeId, BrowseName=ResourceId, carries
  Meta-prefixed members, stable Xid (resource path without version),
  Delete wired to Resource-delete semantics (checks MetaEpoch).
- Versions folder: typed ResourceVersionsType, stable NodeId.
- Version nodes: child of Versions folder, BrowseName=VersionId,
  Xid includes /versions/<VersionId>, Delete wired to Version-delete
  semantics (checks that Version's Epoch).

Delete role is now determined by structural position (the wired
handler), never inferred from IsDefaultVersion/m_resourcesByXid.

Event SourceNode: ResourceCreated -> logical Resource NodeId;
VersionCreated -> exact Version NodeId.

The flat (non-versioned) path is unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: e716d455-8397-4d22-9c5a-398847ab7317
marcschier and others added 8 commits September 5, 2026 17:51
…rchy

- Update xRegistry projection engine tests to expect the new distinct
  Resource/Versions/Version hierarchy where delete role is fixed by
  structural position, not inferred from IsDefaultVersion.
- Update model parity tests: xRegistry 0.6.0, WoT-Con 1.1,
  292 nodes (was 286).
- Update FindVersionNode helper to disambiguate version nodes from
  logical resource nodes using parent type.
- Add FindLogicalResourceNode helper.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: e716d455-8397-4d22-9c5a-398847ab7317
- WotRegistryService.DeleteProjectedEntityAsync: remove old stale-role
  detection (currentlyLogicalResource != deleteLogicalResource check).
  In the distinct hierarchy, the role is determined by structural
  position and is authoritative from the caller.
- Update model parity tests for new node counts (117 xRegistry, 292 WoT).
- Update WoT lifecycle tests to use logical resource node for
  resource-level operations (delete, meta labels).
- Update integration tests that asserted old flat model NodeId paths.
- Update service-level delete tests to reflect that role cannot become
  stale in the new hierarchy.

All 261 xRegistry and 1343 WotCon tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: e716d455-8397-4d22-9c5a-398847ab7317
…del-version detection

Gap 1: Add IXRegistryProjectedResourceFileHandleForwarder interface and
implement it on WotResourceFileManager/ResourceFileAdapter. Wire the
logical Resource's inherited FileType methods to forward Open/Read/Write/
Close/GetPosition/SetPosition through the resolved default Version's file
manager, pinning the Version at Open time.

Gap 2: Add UsesDistinctHierarchyAsync to XRegistryClient that reads the
xRegistry NamespaceVersion (>=0.6.0 means distinct hierarchy). Thread
the flag through WotRegistryGroupClient so OpenResourceAsync uses the
correct browse strategy. Refactor WotConBrowsePathResolver to accept
the hierarchy flag and skip IsDefault disambiguation when not needed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: e716d455-8397-4d22-9c5a-398847ab7317
…on detection

Add 21 new tests covering:
- Scenario 1: distinct hierarchy NodeIds, BrowseNames, Xids
- Scenario 2: default-switch identity stability, no spurious events
- Scenario 3: delete role fixed by structural position
- Scenario 4: logical Resource file-forwarding wiring (Gap 1)
- Scenario 10: client-side model-version detection (Gap 2)
- IsVersionAtLeast version parsing (12 test cases)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: e716d455-8397-4d22-9c5a-398847ab7317
…ding

Adds genuine functional coverage for the logical-Resource file-handle
forwarding path (IXRegistryProjectedResourceFileHandleForwarder):
forwarded Open conflicts with a direct writer on the same manager and
vice versa (shared single-writer reservation), forwarded write+close
commits and is visible to a direct read, forwarded read matches direct
read, and forwarded GetPosition/SetPosition operate on shared handle
state. Replaces the previous wiring-only null-check assertion for this
scenario.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: e716d455-8397-4d22-9c5a-398847ab7317
…roperty delegation

Fixes four issues found in final review of the distinct Resource/Version
hierarchy:

1. LogicalResourceEntry.Versions was a plain Dictionary, read directly by
   the logical Resource's forwarded Open/Read/Write/Close/GetPosition/
   SetPosition handlers on OPC UA method-dispatch threads, outside the
   engine's reconciliation gate, while reconciliation mutates the same
   dictionary under that gate from a different call. Changed to
   ConcurrentDictionary, which is safe for that concurrent read/write
   pattern without adding blocking synchronization to the synchronous
   Open/Write/GetPosition/SetPosition handlers.

2. LogicalResourceEntry.PinnedHandles was keyed only by the underlying
   uint handle returned by whichever Version's file manager served an
   Open call. Since every Version's manager numbers its own handles
   independently starting from 1, opening via the logical Resource
   against two different Versions (e.g. across a default switch) could
   return the same underlying handle number, letting the second Open
   silently overwrite the first pin and misroute/close the wrong
   Version. Now allocates an engine-owned synthetic handle per Open
   (LogicalResourceEntry.AllocatePinnedHandle) and maps it to a
   PinnedFileHandle(Forwarder, VersionNode, UnderlyingHandle) tuple, so
   two pins never collide even when the underlying numbers do.

3. The logical Resource's inherited FileType Properties (Size, Writable,
   UserWritable, OpenCount, MimeType, LastModifiedTime,
   MaxByteStringLength) were never mirrored from the selected default
   Version, remaining at their uninitialized values. Added
   MirrorFileTypeProperties, called on every reconciliation pass (both
   Resource creation and update) and immediately after a forwarded
   Open/Close, so these Properties reflect the represented Version's
   file state.

4. The logical Resource's (non-Meta) Labels container was created but
   never wired or synced, per ResourceType's delegation to the
   represented Version's attributes. AddAttribute/RemoveAttribute now
   delegate to whichever Version is the currently resolved default
   (resolved dynamically at call time, mirroring the FileType
   forwarding architecture), and the Property children are kept in
   sync with the default Version's labels on every reconciliation pass.

Adds five focused regression tests: handle-collision-across-default-switch,
concurrent reconcile/open safety, FileType Property delegation, and Labels
sync/delegation (read and write sides).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: e716d455-8397-4d22-9c5a-398847ab7317
…ation, version compare

Fixes three issues found in a second final review:

1. The logical Resource's Close handler removed a session's synthetic
   file handle pin (TryRemove) BEFORE forwarding to the underlying
   Version's file manager, and forwarded unconditionally regardless of
   which session was calling. A different session guessing or replaying
   another session's synthetic handle number would strip that pin; the
   underlying manager then correctly rejects the mismatched session with
   BadUserAccessDenied and keeps its writer reservation open, but the
   rightful owner's own later Close could no longer find its pin at this
   layer — stranding the handle and its writer slot permanently. Added
   SessionId to PinnedFileHandle (captured at Open time) and a
   SessionIdOf helper; Close now peeks the pin (TryGetValue), rejects a
   session mismatch outright with BadUserAccessDenied without removing
   the pin or forwarding to the underlying manager, and only removes the
   pin after forwarding once ownership is confirmed (at which point every
   underlying outcome, good or bad, has already consumed the underlying
   handle).

2. MirrorFileTypeProperties sets each mirrored child PropertyState's own
   Value (Size, OpenCount, ...), which marks that CHILD's change mask,
   not the logical Resource node's own mask. The subsequent
   ClearChangeMasks(includeChildren: false) call in the Open/Close
   handlers therefore only processed the node's own (never-dirtied) mask
   and left the mirrored children's masks uncleared/unreported until a
   later full reconciliation pass. Changed to includeChildren: true in
   both handlers so mirrored child Properties are cleared and their
   subscribers notified promptly.

3. XRegistryClient.IsVersionAtLeast treated a version string with fewer
   than 3 components as if omitting a component were a parse failure,
   returning the strict "maj > major" comparison instead of treating the
   missing minor/patch as 0. This made IsVersionAtLeast("1", 1, 0, 0)
   return false even though "1" is equivalent to "1.0.0" (which is
   exactly equal to the 1.0.0 threshold). Rewrote the parser to default
   missing minor/patch to 0 (not a failure) while still returning false
   for a present-but-unparseable component, matching the documented
   "false on any parse failure" contract more precisely than before.

Adds three new tests and 7 new parameterized cases: a cross-session
malicious-Close regression proving the rightful owner can still close
and release the writer slot, a change-mask propagation regression
proving a mirrored child Property's subscriber is notified on
Open/Close, and IsVersionAtLeast cases covering the single/two-component
equal-version bug and adjacent boundaries.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: e716d455-8397-4d22-9c5a-398847ab7317
@marcschier marcschier changed the title Add native xRegistry events and version semantics Add native xRegistry events and distinct Resource versions Sep 5, 2026
Keep the WoT Connectivity draft documented as model version 1.1 and eliminate all repository CA1861 diagnostics by reusing immutable expected-value arrays and removing obsolete suppressions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b605797f-a97a-4cd0-8f12-016d33c2fd88
Preserve the distinct Resource/Version hierarchy updates while integrating the repository-wide CA1861 and WoT model-version review fixes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b605797f-a97a-4cd0-8f12-016d33c2fd88
Synchronize the documentation with the xRegistry 0.6.0 hierarchy and eliminate analyzer warnings introduced by the concurrent client and projection-test updates.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b605797f-a97a-4cd0-8f12-016d33c2fd88
Use awaited lifecycle, node mutation, event notification, and cleanup paths for registration, fast-path, and federation managers. Preserve constructors, options, and model identities; update async hosting and migration guidance with cancellation, reentrancy, and cleanup regression coverage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 7ef369a5-2307-4f71-8a11-15af0e72f240
@marcschier
marcschier marked this pull request as ready for review September 7, 2026 11:34
Copilot AI lite review requested due to automatic review settings September 7, 2026 11:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

It spans cross-cutting behavioral and lifecycle changes (async node managers, hierarchy semantics, events) and includes a concurrency-sensitive reconcile queue that should be hardened before approval.

Pull request overview

This PR updates the xRegistry and WoT Connectivity stack to support the xRegistry 0.6.0 distinct Resource/Version hierarchy and introduces native xRegistry event support, while refactoring affected node managers and clients to use the async node-manager lifecycle and updating tests/docs accordingly.

Changes:

  • Extend source generation and client/server logic to support distinct Resource vs Version nodes (and version-aware behaviors like default-version selection and epoch semantics).
  • Add native xRegistry event support (event record generation/readers + server option validation + notifier chain wiring).
  • Broad test sweep and documentation updates (including analyzer-driven CA1861 cleanups and updated NodeSet/model parity expectations).
File summaries
File Description
tools/Opc.Ua.SourceGeneration.Core/Generators/EventRecordGenerator.cs Extends event-record type mapping (UriString handling, new reader mappings).
tests/Opc.Ua.XRegistry.Tests/XRegistryVersionAssignmentTests.cs Migrates tests to async node-manager address space creation.
tests/Opc.Ua.XRegistry.Tests/XRegistryServerTestHarness.cs Updates server harness setup for async node managers/type tree (BaseEventType).
tests/Opc.Ua.XRegistry.Tests/XRegistryRegistryRootTests.cs Migrates root publication tests to async address space creation.
tests/Opc.Ua.XRegistry.Tests/XRegistryFileModeTests.cs Async address space creation + minor assertion literal update.
tests/Opc.Ua.XRegistry.Tests/XRegistryFederationNodeManagerTests.cs Async address space creation + federation identity expectations for 0.6 hierarchy.
tests/Opc.Ua.XRegistry.Tests/XRegistryFastPathNodeManagerTests.cs Async address space creation coverage for fast-path manager.
tests/Opc.Ua.XRegistry.Tests/XRegistryDeleteTests.cs Async address space creation + store tuple helper + delete semantics tests.
tests/Opc.Ua.XRegistry.Tests/XRegistryConcurrentReadTests.cs Async address space creation + gated store concurrency coverage.
tests/Opc.Ua.XRegistry.Tests/XRegistryCloseDeleteRaceTests.cs Async address space creation + deterministic close/delete race tests.
tests/Opc.Ua.XRegistry.Tests/XRegistryClientTests.cs Adds version-parsing test coverage for hierarchy detection logic.
tests/Opc.Ua.XRegistry.Tests/XRegistryAttributeTests.cs Async address space creation + meta attribute surface assertions.
tests/Opc.Ua.XRegistry.Tests/Opc.Ua.XRegistry.Tests.csproj Adds additional project references for updated test infrastructure.
tests/Opc.Ua.WotCon.Tests/WotRegistryNodeManagerTests.cs New tests for reconcile-queue sequencing under contention.
tests/Opc.Ua.WotCon.Tests/WotRegistryClientLiveServerTests.cs Updates expectation for honoring caller-supplied version IDs.
tests/Opc.Ua.WotCon.Tests/WotConModelSourceParityTests.cs Updates model parity expectations (versions, publication dates, node counts).
tests/Opc.Ua.WotCon.Tests/RuntimeNodeSet/WotRegistryLifecycleTests.cs Updates runtime NodeId expectations for logical Resource vs Version nodes.
tests/Opc.Ua.WotCon.Tests/Registry/WotRegistryModelTests.cs Adds version “With(...)”/digest/incarnation behavior coverage.
tests/Opc.Ua.WotCon.Tests/Registry/WotRegistryLabelsServiceTests.cs Adds projection-only semantics coverage for version-label mutations.
tests/Opc.Ua.WotCon.Tests/Materialization/WotProjectionViewCoordinatorTests.cs Adds regression coverage for retired nested projections not reactivating.
tests/Opc.Ua.WotCon.Tests/Materialization/WotMaterializationTestSupport.cs Adds injectable failure path for projection reload in test host.
tests/Opc.Ua.WotCon.Tests/Materialization/WotMaterializationCoordinatorTests.cs Adds placeholder/contentless version refresh behavior test.
tests/Opc.Ua.WotCon.Tests/Materialization/WotDependencyGraphTests.cs Hoists expected arrays to avoid repeated literal allocations.
tests/Opc.Ua.WotCon.Tests/Materialization/WotDeleteBoundaryTests.cs Adds coordinator delete-capability rejection coverage.
tests/Opc.Ua.WotCon.Tests/Client/WotRegistryClientTests.cs Adds client behavior coverage for placeholder claim/retry/legacy cases.
tests/Opc.Ua.WotCon.Tests/Client/WotRegistryBulkLoadTests.cs Updates bulk-load outcomes to track Version node ids/version ids.
tests/Opc.Ua.WotCon.Tests/Client/WotConBrowsePathResolverTests.cs Adds browse-path disambiguation test for colliding flat browse names.
tests/Opc.Ua.WotCon.Samples.Tests/WotSampleEndToEndTests.cs Updates sample flow to set default version after upload result.
tests/Opc.Ua.WotCon.Bindings.Tests/WotEventDataTests.cs Hoists expected arrays + tightens string comparison usage.
tests/Opc.Ua.VisualInspection.Tests/Opc.Ua.VisualInspection.Tests.csproj Removes CA1861 from NoWarn list.
tests/Opc.Ua.Vision.Tests/VisionServerOptionsTests.cs Hoists constant arrays for CA1861 cleanup.
tests/Opc.Ua.Vision.Tests/VisionResultAndFrameGraphTests.cs Hoists arrays for CA1861 cleanup (strings/doubles).
tests/Opc.Ua.Vision.Tests/VisionMethodSurfaceTests.cs Hoists expected argument-name arrays for CA1861 cleanup.
tests/Opc.Ua.Vision.Tests/VisionInferenceServiceTests.cs Hoists arrays for CA1861 cleanup.
tests/Opc.Ua.Vision.Tests/VisionHostingCoverageTests.cs Hoists namespace array for CA1861 cleanup.
tests/Opc.Ua.Vision.Tests/VisionCoordinateFrameMathTests.cs Hoists numeric arrays for CA1861 cleanup.
tests/Opc.Ua.Vision.Tests/Opc.Ua.Vision.Tests.csproj Removes CA1861 from NoWarn list.
tests/Opc.Ua.Vision.Intent.Tests/VisionSubmissionValidationTests.cs Hoists numeric arrays for CA1861 cleanup.
tests/Opc.Ua.Vision.Intent.Tests/VisionOnServerPerceptionTests.cs Hoists expected string arrays for CA1861 cleanup.
tests/Opc.Ua.Vision.Intent.Tests/VisionOffServerPerceptionTests.cs Hoists numeric arrays for CA1861 cleanup.
tests/Opc.Ua.Vision.Intent.Tests/Opc.Ua.Vision.Intent.Tests.csproj Removes CA1861 from NoWarn list.
tests/Opc.Ua.Types.Tests/Schema/NodeSetAliasCompleterTests.cs Hoists expected arrays for CA1861 cleanup.
tests/Opc.Ua.Subscriptions.Tests/SubscriptionServicesTests.cs Removes file-level CA1861 suppression and hoists constants.
tests/Opc.Ua.Subscriptions.Tests/MonitoredItemServicesTests.cs Removes file-level CA1861 suppression and hoists constants.
tests/Opc.Ua.SourceGeneration.Tests/NodesetEventRecordTests.cs Extends nodeset fixture + asserts new reader usage and UriString ABI.
tests/Opc.Ua.SourceGeneration.Core.Tests/CompilerUtils.cs Adds stub methods for new event field readers.
tests/Opc.Ua.Server.Tests/RoleManagerTests.cs Removes file-level CA1861 suppression (cleanup).
tests/Opc.Ua.Server.Tests/Historian/InMemoryHistorianProviderGapsTests.cs Removes file-level CA1861 suppression (cleanup).
tests/Opc.Ua.Server.Tests/AliasNames/AliasNameMethodDispatcherTests.cs Removes CA1861 suppression + hoists arrays.
tests/Opc.Ua.Security.Certificates.Tests/CertificateManager/DefaultCertificateFactoryTests.cs Removes local CA1861 suppression (cleanup).
tests/Opc.Ua.Robotics.Tests/RobotIntentHostingComplianceTests.cs Hoists numeric arrays for CA1861 cleanup.
tests/Opc.Ua.Robotics.Tests/Opc.Ua.Robotics.Tests.csproj Removes CA1861 from NoWarn list.
tests/Opc.Ua.Robotics.Tests/IntentScopeExtensionTests.cs Hoists numeric arrays for CA1861 cleanup.
tests/Opc.Ua.Robotics.Tests/IntentHostingCoverageTests.cs Hoists numeric arrays for CA1861 cleanup.
tests/Opc.Ua.Robotics.Tests/IntentFacetBuilderTests.cs Hoists arrays for CA1861 cleanup.
tests/Opc.Ua.Robotics.Tests/IntentControllerHostStructuralFailureTests.cs Hoists expected arrays for CA1861 cleanup.
tests/Opc.Ua.Robotics.Tests/IntentControllerExecutorResolutionTests.cs Hoists expected arrays for CA1861 cleanup.
tests/Opc.Ua.Robotics.Tests/IntentBuilderComplianceTests.cs Hoists numeric arrays for CA1861 cleanup.
tests/Opc.Ua.Robotics.Tests/BinPickingTargetProviderTests.cs Hoists numeric arrays for CA1861 cleanup.
tests/Opc.Ua.Robotics.Tests/BinPickingPalletizerKinematicsTests.cs Hoists numeric arrays for CA1861 cleanup.
tests/Opc.Ua.Robotics.Intent.Tests/RobotIntentLiveChannelTests.cs Hoists expected arrays for CA1861 cleanup.
tests/Opc.Ua.Robotics.Intent.Tests/Opc.Ua.Robotics.Intent.Tests.csproj Removes CA1861 from NoWarn list.
tests/Opc.Ua.Redundancy.Server.Tests/Raft/HybridSharedKeyValueStoreTests.cs Removes CA1861 suppression + hoists arrays.
tests/Opc.Ua.Redundancy.Client.Tests/ReplicatedClientKeyValueStoreTests.cs Removes file-level CA1861 suppression (cleanup).
tests/Opc.Ua.Redundancy.Client.Tests/Raft/RaftSharedKeyValueStoreTests.cs Removes file-level CA1861 suppression (cleanup).
tests/Opc.Ua.Redundancy.Client.Tests/Raft/RaftLeaderElectionTests.cs Removes file-level CA1861 suppression (cleanup).
tests/Opc.Ua.Redundancy.Client.Tests/Raft/InProcessRaftConsensusTests.cs Removes file-level CA1861 suppression (cleanup).
tests/Opc.Ua.Redundancy.Client.Tests/Raft/HybridSharedKeyValueStoreTests.cs Removes CA1861 suppression + hoists arrays.
tests/Opc.Ua.Positioning.Tests/Opc.Ua.Positioning.Tests.csproj Removes CA1861 from NoWarn list.
tests/Opc.Ua.OpenUsd.Tests/VariantBranchTests.cs Hoists expected arrays for CA1861 cleanup.
tests/Opc.Ua.OpenUsd.Tests/VariantBranchConversionTests.cs Hoists expected arrays for CA1861 cleanup.
tests/Opc.Ua.OpenUsd.Tests/UsdValueCoercionTests.cs Hoists expected arrays for CA1861 cleanup.
tests/Opc.Ua.OpenUsd.Tests/UsdTimeSampleTests.cs Hoists expected arrays for CA1861 cleanup.
tests/Opc.Ua.OpenUsd.Tests/UsdaValueParsingTests.cs Hoists expected arrays for CA1861 cleanup.
tests/Opc.Ua.OpenUsd.Tests/UsdaReaderPlantTests.cs Hoists expected arrays for CA1861 cleanup.
tests/Opc.Ua.OpenUsd.Tests/UsdaReaderCellTests.cs Hoists expected arrays for CA1861 cleanup.
tests/Opc.Ua.OpenUsd.Tests/TypedPrimInstanceTests.cs Hoists expected arrays for CA1861 cleanup.
tests/Opc.Ua.OpenUsd.Tests/TimeSampleMaterializationTests.cs Hoists expected arrays for CA1861 cleanup.
tests/Opc.Ua.OpenUsd.Tests/SceneFidelityRoundTripTests.cs Hoists expected arrays for CA1861 cleanup.
tests/Opc.Ua.OpenUsd.Tests/PrimMetadataMaterializationTests.cs Hoists expected arrays for CA1861 cleanup.
tests/Opc.Ua.OpenUsd.Tests/Opc.Ua.OpenUsd.Tests.csproj Removes CA1861 from NoWarn list.
tests/Opc.Ua.OpenUsd.Tests/MaterializerTests.cs Hoists expected arrays for CA1861 cleanup.
tests/Opc.Ua.OpenUsd.Tests/ConversionFixTests.cs Hoists expected arrays for CA1861 cleanup.
tests/Opc.Ua.OpenUsd.Tests/ConversionEmitPathTests.cs Hoists expected arrays for CA1861 cleanup.
tests/Opc.Ua.OpenUsd.Tests/ConversionAsymmetryTests.cs Hoists expected arrays for CA1861 cleanup.
tests/Opc.Ua.OpenUsd.Tests/ConnectionPathsMemberTests.cs Hoists expected arrays for CA1861 cleanup.
tests/Opc.Ua.OpenUsd.Tests/ConnectionFidelityTests.cs Hoists expected arrays for CA1861 cleanup.
tests/Opc.Ua.Lds.Tests/LdsMeConformanceTests.cs Removes file-level CA1861 suppression (cleanup).
tests/Opc.Ua.Lds.Tests/DiscoveryDepthTests.cs Removes CA1861 suppression + hoists arrays.
tests/Opc.Ua.InformationModel.Tests/BaseInformationTests.cs Removes file-level CA1861 suppression (cleanup).
tests/Opc.Ua.InformationModel.Tests/AttributeWriteTests.cs Removes CA1861 suppression + hoists arrays.
tests/Opc.Ua.InformationModel.Tests/AliasnameOptionalMethodsTests.cs Removes CA1861 suppression + hoists arrays.
tests/Opc.Ua.InformationModel.Tests/AliasnameHierarchyTests.cs Removes CA1861 suppression + hoists arrays.
tests/Opc.Ua.InformationModel.Tests/AliasnameBaseTests.cs Removes file-level CA1861 suppression (cleanup).
tests/Opc.Ua.History.Tests/DataAccessDepthTests.cs Removes CA1861 suppression + hoists arrays.
tests/Opc.Ua.Gds.Tests/GdsTestFixture.cs Removes CA1861 suppression + hoists arrays.
tests/Opc.Ua.Gds.Tests/GdsQueryApplicationsTests.cs Removes CA1861 suppression + hoists arrays.
tests/Opc.Ua.Gds.Tests/GdsApplicationDirectoryTests.cs Removes CA1861 suppression + hoists arrays.
tests/Opc.Ua.Di.Tests/PackageStoreTests.cs Removes file-level CA1861 suppression (cleanup).
tests/Opc.Ua.Core.Tests/Stack/State/NodeStateTests.cs Adds onboarding namespace constant/index in test context.
tests/Opc.Ua.Core.Tests/Stack/Client/EventRecordFieldReadersTests.cs Adds tests for new event-field readers + UriString ABI expectations.
tests/Opc.Ua.Client.Tests/Streaming/StreamingSubscriptionExtensionsTests.cs Narrows pragma suppression (removes CA1861).
tests/Opc.Ua.Client.Tests/FileSystem/FileSystemClientEnumerationTests.cs Removes file-level CA1861 suppression (cleanup).
tests/Opc.Ua.Client.Tests/ClientBuilder/ManagedSessionBuilderTests.cs Removes local CA1861 suppression (cleanup).
tests/Opc.Ua.AI.Tests/AiServerTestHarness.cs Adds BaseEventType subtype to AI test type table.
src/Opc.Ua.XRegistry/NugetREADME.md Updates package docs for structural identity + events surface.
src/Opc.Ua.XRegistry/IResourceContentIdProvider.cs Clarifies content-key semantics vs structural identity in docs.
src/Opc.Ua.XRegistry.Server/XRegistryServiceCollectionExtensions.cs Updates DI docs wording for content-key provider.
src/Opc.Ua.XRegistry.Server/XRegistryServerOptions.cs Adds event configuration options + validation + federation structural ids.
src/Opc.Ua.XRegistry.Server/XRegistryNodeManagerStartup.cs Adds staged startup/rollback helper for async node manager initialization.
src/Opc.Ua.XRegistry.Server/XRegistryFastPathNodeManager.cs Converts fast-path node manager to async lifecycle + staged startup.
src/Opc.Ua.XRegistry.Server/NugetREADME.md Expands server package docs for hierarchy/events/async lifecycle.
src/Opc.Ua.XRegistry.Client/XRegistryClient.cs Adds cached distinct-hierarchy detection + version parsing helper.
src/Opc.Ua.XRegistry.Client/NugetREADME.md Updates client package docs for content-key and events.
src/Opc.Ua.WotCon/Opc.Ua.WotCon.csproj Adds CS0108 suppression for generated member hiding.
src/Opc.Ua.WotCon/Design/Opc.Ua.WotCon.NodeSet2.csv Adds Versions-folder object types and members for new hierarchy.
src/Opc.Ua.WotCon.Server/WotRegistryServerOptions.cs Adds optional xRegistry event configuration surface.
src/Opc.Ua.WotCon.Server/WotRegistryNodeManager.cs Introduces reconcile queue + root notifier registration + reconcile flow updates.
src/Opc.Ua.WotCon.Server/Registry/WotRegistryPersistenceBounds.cs Clarifies max-versions semantics w/ contentless pending version allowance.
src/Opc.Ua.WotCon.Client/WotRegistryGroupClient.cs Adds distinct-hierarchy-aware resource resolution and placeholder claim logic.
src/Opc.Ua.WotCon.Client/WotRegistryClient.cs Plumbs distinct-hierarchy detection + bulk-load/version upload behavior updates.
src/Opc.Ua.Core/Stack/Client/EventRecordFieldReaders.cs Adds new readers for nullable UInt32 and string-array event fields.
src/Opc.Ua.AI/Model/Opc.Ua.AI.NodeSet2.xml Updates AI model version + required xRegistry model version metadata.
docs/WoTConnectivity.md Updates documentation model table and xRegistry node count/event note.
docs/README.md Updates xRegistry doc blurb for structural identity + events.
Review details
  • Files reviewed: 145/162 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/Opc.Ua.WotCon.Server/WotRegistryNodeManager.cs
Comment thread docs/XRegistry.md Outdated
@marcschier marcschier added the ready Ready to merge once CI Passes label Sep 7, 2026
marcschier and others added 3 commits September 7, 2026 17:50
Address documentation feedback on OPCFoundation#4396: these managers are new in 2.0. Describe the current async lifecycle instead of migration from unreleased synchronous APIs, retaining hosting and cleanup guidance.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7ef369a5-2307-4f71-8a11-15af0e72f240
Address queue-liveness review feedback on OPCFoundation#4396. A faulted or canceled callback left m_running set and stranded subsequent changes. Release ownership in finally and restart accepted pending work without racing normal idle handoff. Preserve failure observation for idle/completion waiters.

Add deterministic fault, cancellation, queued-work, and completion regressions. The four new cases reproduce the defect before the fix; all 55 targeted queue and live event/projection/lifecycle cases pass on net10.0 and net48.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7ef369a5-2307-4f71-8a11-15af0e72f240
Integrate upstream e8bec27 (OPCFoundation#4431) while preserving the xRegistry 0.6 event and distinct Resource/Version model. Combine deferred declaration-aware binding preparation and linked partition coalescing with enabled-member gating and retirement accounting, including the new failure paths.

Keep both dependency-graph improvements and reusable expected arrays. Align the incoming namespace metadata contract test with the existing September 5 model publication date; both authoritative NodeSets remain byte-identical.

Validation: 454 targeted WoT/materialization/model/registry tests and all 327 XRegistry tests passed on both net10.0 and net48. All 29 net10 aggregation sample tests passed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7ef369a5-2307-4f71-8a11-15af0e72f240
@marcschier
marcschier enabled auto-merge (squash) September 7, 2026 18:31
@marcschier
marcschier merged commit da7412c into OPCFoundation:master Sep 8, 2026
500 of 506 checks passed
marcschier added a commit that referenced this pull request Sep 8, 2026
# Description

Make startup-composed application NodeManagers participate in the live
lifecycle and bind imported NodeSet2 Method argument properties to their
typed `MethodState` children.

This change:

- adopts application NodeManagers created before startup into
`INodeManagerLifecycle.Registrations` after server startup succeeds,
while keeping diagnostics, configuration, and core managers protected;
- retains per-manager startup external-reference ownership and exact
routing positions so reload, removal, rollback, overlapping namespaces,
synchronous adapters, and server restart preserve existing behavior;
counted immutable reference snapshots avoid quadratic startup matching;
- rejects duplicate factory output across active, unpublished, and
retired lifecycle generations without deleting or disposing the live
manager; callers can catch the public
`NodeManagerAlreadyRegisteredException`;
- binds valid namespace-zero `Argument[]` `PropertyType`
`InputArguments` and `OutputArguments` Variables to
`MethodState.InputArguments` and `MethodState.OutputArguments` from
either `HasProperty` direction, without requiring `ParentNodeId`,
including local namespace-URI reference targets;
- preserves authored metadata during NodeSet typed-child promotion
without changing the initialization behavior of unrelated generated
nodes;
- retains generic-import guards for custom and malformed signatures,
duplicate standard-signature validation, and upstream factory-driven
generated-slot replacement and reconciliation callbacks;
- updates lifecycle and Runtime NodeSet documentation and clarifies
`OnServerStartedAsync` timing for both `StartAsync` overloads, including
the unopened default host returned to the caller.

This is a focused follow-up to #4418. That PR preserves registrations
from multiple fluent builders, but does not change lifecycle ownership
or NodeSet child typing. The branch includes upstream `master` through
`da7412c42`, including #4396, #4432, #4437, #4438, and #4440.

The completed review fixes in `686d0561f` are included. The latest base
merge (`a29fc6ca8`) combines them with #4432's shared batch/fluent
importer and generated state factories. One iterative linker supports
available parent nodes, deferred parent side tables, application-owned
handles, and placeholder reconciliation while retaining reference-driven
Method argument binding and URI handling. Upstream cancellation, GDS
assembly renames, certificate leak scoping, and xRegistry changes are
preserved.

## Related Issues

- Fixes #4421
- Fixes #4422

## CI regression fix

`e1a4436f0` fixes the GDS failure reported on Ubuntu and macOS. Copying
permission metadata in general `NodeState` initialization applied
`SecurityAdmin`-only defaults to generated GDS custom certificate groups
and denied their existing GDS-admin Browse requests. Metadata
preservation is now confined to NodeSet typed-child promotion; imported
Method argument permissions remain intact, while unrelated generated
nodes retain their existing initialization behavior.

Local Release validation also exposed a 260-character certificate path
in the startup-failure test added by this PR. Its isolated PKI now uses
a short temporary path. No assertions, authorization checks, or CI gates
were weakened, and no pre-existing tests were changed.

## macOS ARM64 NativeAOT suspension

Per maintainer request, `a15971f32` suspends only the failing
`macos-latest` / `osx-arm64` NativeAOT matrix entry. Re-enabling it once
the compiler contains the runtime fix is tracked in #4443. Intel macOS,
Linux, and Windows NativeAOT coverage, managed macOS tests, and all
other CI gates remain enabled. This is an explicit coverage suspension,
not a claim that the underlying compiler/linker defect is fixed.

The macOS ARM64 NativeAOT job on `a29fc6ca8` fails during native linking
with
`ld: Assertion failed: (_addend == uniqueIndex && "too many large
addends")`.
Both attempts of [run
34191755950](https://github.com/OPCFoundation/UA-.NETStandard/actions/runs/34191755950)
hit the same assertion before the native test executable can run; the
build/test summary failure is downstream.

This matches the NativeAOT Mach-O relocation issue in
dotnet/runtime#119380, fixed by relocation-anchor emission in
dotnet/runtime#124721 and its .NET 10 backport dotnet/runtime#132171.
The failing `Microsoft.DotNet.ILCompiler` 10.0.11 package's nuspec
points to `dotnet/dotnet` commit
`e2f47b0110ed922f21a1522da67279133ce28f32` (July 23); its object writer
does not contain the anchor fix merged on August 12. Version 10.0.11 is
currently the latest stable package.

The base commit passed on the same runner image and SDK, so this is not
being dismissed as a generally broken runner or a test flake. The
precise PR-specific object-layout trigger has not been isolated. A
compiler containing the relocation fix is needed before restoring the
lane. No test code, assertions, coverage thresholds, or shared tooling
settings were changed.

## Validation

Latest base-merge validation on both `net10.0` and `net48`, Release:

- Import helpers and argument-binding regressions: 51 passed per
framework.
- Batch/fluent import, generated-state overlays, runtime/startup
lifecycle, cross-source references, routing, reference snapshots, and
node-authoring selection: 344 passed per framework.
- Merge-specific cases cover available Method parents with
forward/inverse and URI/index references while retaining an
application-owned `NodeId` handle.
- The unchanged upstream `NodeSetImportIntegrationTests.cs:210` CA1861
warning remains; no diagnostic suppression or unrelated cleanup was
added.

Release CI-fix validation on both `net10.0` and `net48`:

- `CustomCertificateGroupIntegrationTest`: 4 passed, including the
unchanged CI failure.
- `UANodeSetHelpersTests`: 8 passed, including imported security
metadata.
- `StartupRuntimeNodeSetLifecycleTests`: 5 passed.

Earlier Debug merge and review validation on both frameworks:

- Lifecycle, RuntimeNodeSet, fluent, and OperationContext selection
after merging `978e6d1af`: 638 passed per framework.
- Startup/transport-binding and RuntimeNodeSet integration selection
after merging `017856f4a`: 28 passed per framework.
- Public exception contract and duplicate-registration selection in
`fbf08428b`: 6 passed per framework.

Targeted test invocations rebuilt the affected projects successfully.
The full `UA.slnx` suite was not rerun locally.

## Checklist

- [ ] I have signed the
[CLA](https://opcfoundation.org/license/cla/ContributorLicenseAgreementv1.0.pdf)
and read the
[CONTRIBUTING](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/CONTRIBUTING.md)
doc.
- [x] I have added tests that prove my fix is effective or that my
feature works and increased code coverage.
- [x] I have added all necessary documentation.
- [x] I have verified that my changes do not introduce (new) build or
analyzer warnings.
- [ ] I ran **all** tests locally using the **UA.slnx** solution against
at least .net **framework** and .net **10**, and all passed.
- [ ] I fixed **all** failing and flaky tests in the CI pipelines and
**all** CodeQL warnings.
- [x] I have addressed **all** PR feedback received.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2bb8a834-7695-4ae6-84cb-2471c76d1b12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready Ready to merge once CI Passes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants