Files
mxaccess/docs/ASB-Native-Integration-Decision.md
T
Joseph Doherty fe2a6db786
rust / build / test / clippy / fmt (push) Has been cancelled
Initial project state: .NET reference, design, Rust port (M0+M1), evidence
Layout:
- src/                    .NET 10 x64 reference: MxNativeCodec, MxNativeClient,
                          MxAsbClient, probes, tests, harnesses. Executable spec.
- design/                 Architectural plan for the Rust port (M0–M6), error
                          model, protocol invariants, risks (R1–R16), adversarial
                          review log (review.md).
- rust/                   Rust workspace. M0 skeleton + M1 codec parity.
                          mxaccess-codec: 215 unit tests + 2 cross-implementation
                          parity tests (byte-identical against .NET reference).
                          Other crates are M0 stubs awaiting M2+.
- captures/               Frida + netsh + pcap evidence per CLAUDE.md
                          ("captures are evidence, not throwaway logs").
- analysis/               Decompiled C# (frida/proxy/decompiled-*),
                          Ghidra exports for native DLLs (`exports/` only —
                          working state at `projects/` and AVEVA's input
                          binaries at `input/` are gitignored).
- docs/                   Reverse-engineering reference docs.
- tools/                  Setup-LiveProbeEnv.ps1 (Infisical credential fetcher),
                          Compute-Crc.ps1 (.NET parity helper).
- .github/workflows/      Rust CI: fmt + build + test + clippy on Windows.
- LICENSE                 MIT (Joseph Doherty, 2026).

Verified:
- cargo test --workspace → 217 passed (215 unit + 2 .NET parity), 0 failed
- cargo clippy --workspace -- -D warnings → clean
- cargo fmt --all -- --check → clean
- cargo publish --dry-run -p mxaccess-codec → packages cleanly

Excluded from history (see .gitignore):
- **/bin, **/obj, **/target — build artifacts
- analysis/ghidra/projects/ — Ghidra working state (regenerable)
- analysis/ghidra/input/ — AVEVA proprietary DLLs (vendor IP)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 06:21:00 -04:00

7.3 KiB

ASB / Native Integration Decision

Decision

Use MxAsbClient as the preferred implementation for the regular tag data plane. Do not embed ASB inside the current MxNativeSession transport. Instead, introduce a higher-level compatibility facade that can route each MXAccess-style operation to either ASB or native NMX behind a common server/item-handle model.

The boundary should be operation-based, not inheritance-based:

  • ASB owns direct IASBIDataV2 connect, register, unregister, read, write, write-completion polling, publish subscriptions, cleanup, and explicit reconnect.
  • Native NMX owns COM/DCOM activation, NMX service registration, callback export, Galaxy repository metadata resolution, native subscription callbacks, native recovery replay, and MXAccess behaviors whose ASB equivalent is not proven.
  • The existing MxNativeClient should remain available as the native fallback and diagnostic path. ASB can replace its basic scalar/array read/write and simple data-change usage only after a shared facade makes routing explicit.

This avoids coupling the WCF ASB channel lifecycle to the DCE/RPC callback lifecycle while still letting callers move to the simpler pure-managed x64 ASB path where evidence is strongest.

Evidence

Current ASB evidence is strong for the normal data path:

  • The pure .NET 10 x64 ASB client connects to the live IASBIDataV2 net.tcp endpoint, authenticates from local DPAPI-protected solution material, and performs register/read/write without AVEVA assembly references.
  • ASB register/read/write is live-proven for deployed scalar and array tags, and PublishWriteComplete supplies write-handle completion records for basic writes.
  • ASB subscriptions can create subscriptions, add monitored items, publish values, map quality/status payloads, and raise an MXAccess-like data-change event through MxAsbCompatibilityServer.
  • ASB now has public option objects for connection, write, write completion, subscriptions, monitored items, cleanup, and reconnect.

Current native evidence is still required for legacy semantics:

  • MxNativeSession owns NMX service activation, DCE/RPC transport, callback sink registration, heartbeat/recovery, Galaxy metadata resolution, NMX write message projection, Write2, WriteSecured2, supervisory advise, buffered registration, and callback parsing.
  • MxNativeCompatibilityServer models the fuller MXAccess surface: AddItem2, AuthenticateUser, ArchestrAUserToId, Suspend, Activate, AdviseSupervisory, OnWriteComplete, OperationComplete, and OnBufferedDataChange.
  • Direct IASBIDataV2 exposes no activate, suspend, or generic OperationComplete operation. It only exposes write-completion polling.
  • ASB buffered monitored items are accepted by the observed provider, but publish still returns one current value rather than a native buffered sample batch.
  • Direct system-auth ASB writes did not reproduce the public MXAccess secured write rejection path on this VM.

Create a routing layer above both clients. It should hold compatibility server/item handles and choose a backend per operation:

  • Register, Unregister, AddItem, RemoveItem, Read, basic Write, simple Advise, UnAdvise, and write-completion polling should default to ASB when an ASB endpoint is configured and the tag/value shape is supported.
  • Write2, WriteSecured2, AuthenticateUser, ArchestrAUserToId, Suspend, Activate, AdviseSupervisory, buffered items, and native callback-only events should route to native NMX until direct ASB evidence exists.
  • OperationComplete should not be synthesized from ASB write completion. ASB write completion can raise a write-complete event, but generic operation completion remains native-only until a native trigger and payload mapping are proven.
  • The facade should expose which backend handled an item or operation so tests, probes, logs, and callers can distinguish ASB behavior from native fallback.

What ASB Should Own

  • Endpoint discovery/configuration inputs for the direct IASBIDataV2 route.
  • Connection/authentication, request signing, channel cleanup, reconnect, and connection-failure cleanup for ASB.
  • ASB item identity creation, register/unregister/read, variant encode/decode, and supported scalar/array writes.
  • AsbWriteOptions and AsbWriteCompletionOptions driven write completion, including delayed readback when requested.
  • ASB subscription creation, monitored item creation/deletion, publish polling, quality/status mapping, and basic MXAccess-compatible data-change adaptation.
  • ASB-specific result/status summaries that preserve raw provider status while exposing named categories for known cases.

What Native NMX Should Still Own

  • DCE/RPC, COM object reference handling, NTLM/SSPI authentication, callback export, and NMX service registration.
  • Galaxy repository tag resolution and metadata needed for NMX reference handles, value-kind projection, and native buffered registration.
  • Write2 and WriteSecured2 until ASB timestamped and secured-write parity is explicitly proven.
  • Suspend, Activate, supervisory advise, native recovery replay, heartbeat policy, and callback-derived event surfaces.
  • OnBufferedDataChange and generic OperationComplete until ASB produces equivalent runtime evidence.
  • Native diagnostic/probe coverage for payloads that ASB does not expose.

Risks And Unknowns

  • ASB endpoint discovery/configuration is environment-specific; fallback to NMX must be explicit when no usable endpoint is configured.
  • ASB access-denied, no-communication, and other live fault status cases still need safe source conditions before they can be treated as complete parity.
  • The exact native completion-only byte-to-status mapping is not fully proven.
  • ASB buffered publish behavior may vary by provider or configuration; the observed provider did not produce multi-sample batches.
  • Dual routing can create semantic drift if the facade hides backend choice. Backend selection must be visible in diagnostics and test assertions.
  • Mixing ASB and native subscriptions for the same logical item can duplicate callbacks or produce ordering differences; route each item to one backend at a time.

Staged Migration

  1. Add a small shared facade project or class that exposes the MXAccess-style handle API and delegates to MxAsbCompatibilityServer or MxNativeCompatibilityServer.
  2. Start with opt-in ASB routing for basic register/read/write/simple-advise flows. Keep native as the default fallback for unsupported operations.
  3. Add route annotations to events and probe output so every data-change, write-complete, and fallback decision identifies asb or native.
  4. Port basic compatibility tests to run against the facade with ASB-for-data enabled and native fallback enabled. Preserve existing ASB-only and native-only tests.
  5. Gate any additional replacement on evidence: timestamped ASB write behavior, secured-write behavior, buffered sample batches, and native operation-complete parity should each require a focused capture or live probe before moving from native to ASB.
  6. After the facade is stable, treat MxNativeClient as the legacy/native adapter and MxAsbClient as the primary data adapter. Avoid merging their transport internals.