Files
mxaccess/work_remain.md
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

13 KiB

Core Remaining Work

Current Baseline

The pure managed .NET 10 x64 ASB path is feasible and live-proven. It can:

  • read the ASB solution shared secret through DPAPI,
  • authenticate to the live IASBIDataV2 net.tcp endpoint,
  • register/read TestChildObject.TestInt,
  • reject null public collection arguments before touching client state in the main multi-item APIs,
  • decode/read/write the core scalar and array ASB type matrix,
  • write Int32 values and read them back,
  • write through either positional write parameters or AsbWriteOptions,
  • poll PublishWriteComplete for write completion,
  • create a subscription, add monitored items, publish updates, and delete the monitored items/subscription,
  • configure subscription creation and monitored-item registration through stable option records while preserving the original positional overloads,
  • map publish responses into callback-ready values with decoded value, timestamp, quality, ASB status elements, and item-id-to-tag-name resolution,
  • expose publish result summaries and value-presence helpers alongside the raw publish response and mapped values,
  • expose derived publish/data-change status summaries and item-status array summary mapping while preserving raw statuses,
  • raise mapped publish updates through the MxAsbClient PublishedValueReceived event,
  • adapt ASB publish updates into an MXAccess-like server/item-handle DataChanged facade,
  • advise compatibility items through either positional subscription parameters or the shaped AsbSubscriptionOptions / AsbMonitoredItemOptions overload,
  • map known ASB global and item error codes to named AsbErrorCode values,
  • summarize ASB status payload quality/category/detail while preserving raw unknown values,
  • wait for async write completion by handle with timeout, poll interval, and optional delayed readback without retrying the write,
  • cancel write-completion polling before the next poll or during polling/ readback delays through AsbWriteCompletionOptions.CancellationToken,
  • perform idempotent best-effort ASB cleanup with signed Disconnect, independent channel/factory close-or-abort handling, and cleanup result reporting,
  • explicitly reconnect by cleaning up the current ASB channel, retrying connection creation with caller-controlled attempts/delay, returning a fresh client, and preserving attempt plus cleanup evidence without replaying operations,
  • connect through a stable AsbConnectionOptions API object with early endpoint validation and matching compatibility-server register/advise options overloads,
  • keep payload serialization diagnostics out of the public API surface while retaining friend-only probe/test access,
  • bound ASB cleanup disconnect and close operations with caller-controlled timeouts,
  • cancel ASB cleanup before graceful disconnect/close by aborting local channel/factory objects when the cleanup token is already canceled,
  • live-prove canceled cleanup on an opened ASB connection, including skipped disconnect, local channel/factory abort, and RequiresNewConnection,
  • test cleanup partial-failure behavior for closed objects, faulted objects, close failure with abort fallback, abort failure reporting, and configured close timeout propagation,
  • capture safe connection-failure evidence for refused ASB endpoints without destabilizing the live provider,
  • clean up partially-created WCF channel/factory objects when ASB connection setup fails before a disposable client is returned,
  • match installed AVEVA proxy behavior for UnregisterItems,
  • register/read multiple tags in one request.
  • document the supported ASB Variant wire format, scalar/array payload layouts, timestamp/duration handling, and quality/status payload parsing in docs\ASB-Variant-Wire-Format.md,
  • document the recommended ASB/native integration boundary and staged migration in docs\ASB-Native-Integration-Decision.md.

Recent NMX Warning Triage

System Platform warning:

NMX Header ... buffer size pktHeader.dwDataSize 381 doesn't match received message size of 46

The warning is emitted by NmxAdptr.dll in the ProcessDataReceived path, not by the pure ASB client. The 46 byte received size matches the standalone NMX TransferData envelope size. A valid TransferData operation must send the 46-byte envelope plus the declared inner body; if the service receives only the envelope, or any envelope whose inner-length field does not match the actual body length, the adapter logs this class of header-size warning.

Mitigation now applied:

  • src\NmxComHarness no longer sends a default self-transfer body. The --self-transfer path requires explicit --transfer-body-hex, validates the 46-byte envelope length field, and rejects empty/header-only transfers unless --allow-empty-transfer is explicitly supplied for a controlled probe.
  • src\MxNativeClient validates low-level TransferData bodies before sending through both COM and managed DCE/RPC paths.
  • src\MxNativeClient.Probe now requires explicit validated --transfer-body-hex for managed TransferData probes.

Build/test verification after mitigation:

  • dotnet build src\NmxComHarness\NmxComHarness.csproj
  • dotnet build src\MxNativeClient\MxNativeClient.csproj
  • dotnet build src\MxNativeClient.Probe\MxNativeClient.Probe.csproj
  • dotnet run --project src\MxNativeClient.Tests\MxNativeClient.Tests.csproj
  • dotnet run --project src\MxNativeCodec.Tests\MxNativeCodec.Tests.csproj

Remaining Core Work

  1. ASB type matrix

    • Core scalar/array decode, live read, and live write coverage is complete for Boolean, Int32, Float, Double, String, DateTime, Duration, and deployed array tags.
    • Remaining work is adding less common ASB types only as needed by real deployed tags.
    • ASB variant type IDs, payload layout, timestamp handling, duration handling, and quality/status payload parsing are documented in docs\ASB-Variant-Wire-Format.md.
  2. ASB subscriptions and publish

    • CreateSubscription, AddMonitoredItems, Publish, DeleteMonitoredItems, and DeleteSubscription are implemented and live-proven.
    • AsbSubscriptionOptions and AsbMonitoredItemOptions now provide stable option-object overloads for subscription creation and monitored-item registration.
    • Mapped publish updates are exposed through a .NET event and a handle-based data-change facade.
    • The compatibility Advise facade also accepts AsbSubscriptionOptions and AsbMonitoredItemOptions; the probe path can exercise this options overload and live compatibility subscribe has been verified through it.
    • AsbPublishResult now carries a derived result summary and HasValues helper while retaining the raw PublishResponse.
    • AsbPublishedValue and MxAsbDataChangeEvent expose derived StatusSummary helpers for callers that want named status categories without losing raw status elements.
    • Item identity mapping and basic cleanup behavior are live-proven; continue validating callback/update ordering under churn.
  3. Status and error mapping

    • Success-path publish quality/status decoding is implemented for ASB status elements, including MxQuality.
    • Named global/item ASB error-code mapping is implemented, and live probes cover InvalidMonitoredItems, OperationFailed, MonitoredItemsNotFound, WriteFailedBadTypeMismatch, invalid subscription delete global 0x000C, publish 0x0020, and bad-quality value status.
    • Status summaries classify good/uncertain/bad quality, known MX status categories, request timeout detail, and platform/no-communication detail.
    • Broaden remaining live non-success ASB ArchestrAError, item status, quality bytes, and known detail cases into the managed status model when safe source conditions are available, especially access denied and no communication.
    • Safe current-VM probes did not produce access denied or no communication: same-value direct ASB writes to secured/verified booleans succeeded, and a read-only sweep of 20 protected-value tags returned good quality.
    • Preserve unknown payloads without guessing.
    • Tests now cover success, invalid item, wrong-type write completion, invalid cleanup evidence inputs, access denied, timeout, no communication, and async write completion statuses.
  4. Write variants

    • Core scalar and deployed array writes are live-proven beyond basic Int32.
    • AsbWriteOptions now provides an option-object overload for basic writes while preserving the existing positional overloads.
    • Add timestamp/status/comment handling where the provider supports it.
    • Write completion polling by handle with timeout, optional delayed readback, option validation, and caller cancellation is implemented and live-proven for Int32; extend evidence across other supported write shapes.
  5. OperationComplete parity

    • Basic write completion through PublishWriteComplete is proven.
    • Direct IASBIDataV2 has no activate/suspend or generic OperationComplete contract, and create-subscription, add-monitored, publish, delete-monitored, and delete-subscription operations do not enqueue PublishWriteComplete records.
    • Continue trigger search outside the direct IDataV2 write-completion queue if a safe runtime candidate appears.
    • Do not synthesize OperationComplete for operations until native behavior is proven.

5a. Completion-only operation status

  • One-byte NMX completion-only frames are preserved as raw, unpromoted statuses, including 0x00, 0x41, and 0xEF.
  • Only the observed 5-byte status-word frame 00 00 50 80 00 maps to MxStatus.WriteCompleteOk and can raise the MXAccess-compatible write-complete event.
  • Exact native MXSTATUS_PROXY[] conversion for completion-only bytes still needs decompiled mapping evidence or a native public event capture before promotion.
  • Current available decompiled/Ghidra outputs did not expose a mapping table for completion-only bytes.
  1. Buffered data

    • Find a runtime/source condition that emits buffered sample batches.
    • ASB MonitoredItem.Buffered is now exposed and live-proven against TestMachine_001.TestHistoryValue, but the observed publish response still carries one current value rather than a multi-sample buffered batch.
    • Map any proven batch payloads into the compatibility event model.
  2. Production cleanup

    • Reduce trace verbosity and make SOAP/body dumps opt-in.
    • Channel/factory disposal now sends best-effort signed Disconnect, closes channel/factory independently with caller-controlled timeouts, and records cleanup results.
    • Cleanup cancellation is implemented for cancellation requested before graceful disconnect/close starts; already-running synchronous WCF cleanup calls remain bounded by configured timeouts.
    • Canceled cleanup is live-proven on an opened ASB channel and completes via local abort without hanging.
    • Explicit reconnect is implemented and live-proven for the normal cleanup and reconnect path.
    • Resolve additional live partial cleanup behavior after ASB channel failures when a safe provider condition is available.
    • Safe refused-endpoint connection failure evidence is captured; source-level no-communication evidence still needs a safe provider condition.
    • Partial ASB connection setup failure now runs channel/factory close-or-abort cleanup before rethrowing.
  3. Public library shaping

    • The main probe-grade API primitives have been shaped into stable public option/helper surfaces; continue only for concrete caller gaps.
    • AsbConnectionOptions now fronts MxAsbDataClient.Connect, the string overload delegates to it, and MxAsbCompatibilityServer.Register accepts the same options object.
    • AsbWriteOptions now fronts the basic write path while preserving the existing positional write overloads.
    • MxAsbCompatibilityServer.Advise now has an options overload, and the probe can route compatibility subscribe through it.
    • AsbPayloadDebug has been narrowed to an internal friend-only diagnostic helper for test/probe assemblies.
    • AsbWriteCompletionOptions now owns timeout/poll/readback validation and exposes a cancellation token for caller-controlled polling waits.
    • AsbSubscriptionOptions and AsbMonitoredItemOptions now avoid extending positional primitive overloads as subscription policy grows.
    • AsbPublishResult now exposes common summary helpers without hiding raw response details.
    • AsbPublishedValue, MxAsbDataChangeEvent, and AsbResultMapper now expose derived status-summary helpers for common caller paths.
    • Public collection null guards are explicit for the main multi-item APIs.
    • docs\ASB-Native-Integration-Decision.md records the current integration decision: use MxAsbClient as the preferred regular tag data-plane adapter behind a higher-level compatibility routing facade, while keeping native NMX responsible for callback-only and not-yet-proven MXAccess semantics.
    • Focused non-live tests now cover public options defaults/validation, compatibility overload visibility, write-completion/readback DTO shape, and publish-result helpers. Add deeper request-construction tests only where future API growth makes them necessary.
    • Keep compatibility behavior documented where the deployed provider differs from ideal success semantics.