# Current Sprint State Last updated: 2026-04-26 local VM time. ## Build Status - `MxNativeCodec.Tests`: passed. - `MxNativeClient.Tests`: passed, including compatibility surface and recovery lifecycle event checks. - `MxTraceHarness`: Release build passed. - `MxNativeClient.Probe`: Release build passed, including `--probe-session-recover-multi`. - `MxDataConsumerProbe`: Release build passed. It is an x86 .NET Framework probe for `aaMxDataConsumer.dll` / `IDataConsumer`. - `AsbProxyProbe`: Release x64 .NET Framework build passed. It directly loads the MSIL ASB IData proxy/contract assemblies and proves x64 managed discovery, connection, register, read, write, readback, and published write completion against the live MxDataProvider. It also has an unregister compare probe for installed-proxy parity. - `MxAsbClient.Probe`: Release .NET 10 x64 build passed. It is a pure managed ASB client slice with no AVEVA assembly references. It reads the ASB solution shared secret through DPAPI, performs the ASB system-auth handshake, opens the net.tcp `IASBIDataV2` channel, and live validates register, read, write, readback, published write completion, unregister parity, and multi-item register/read for `TestChildObject.TestInt` plus `TestMachine_001.TestHistoryValue`. - `MxAsbClient.Probe`: clean Release build with zero warnings after adding an explicit `System.Security.Cryptography.Xml` `10.0.7` package reference and replacing the obsolete PBKDF2 constructor with `Rfc2898DeriveBytes.Pbkdf2`. - `MxAsbClient.Tests`: passed. The test project covers ASB `Variant` factory and decode/display round trips for bool, int, float, double, string, datetime, duration, and the matching bool/int/float/double/string/ datetime/duration array wire payloads, `MonitoredItemValue` binary serializer round trips for publish responses, and ASB status payload decoding for publish quality/status mapping. It also covers the stable ASB connection options overload, endpoint validation, and friend-only debug payload helper visibility, plus write-completion option validation and cancellation-token surface, subscription/monitored-item option overloads, and publish result summary helpers. Latest focused non-live shaping tests also assert exact defaults and validation boundaries for `AsbConnectionOptions`, `AsbWriteOptions`, `AsbWriteCompletionOptions`, `AsbSubscriptionOptions`, and `AsbMonitoredItemOptions`, DTO shape for write-completion/readback results, null collection argument guards, empty/non-empty `AsbPublishResult` helpers, derived status-summary helpers, item-status array mapping, and both compatibility `Advise` overload signatures. - Credential scan over `analysis`, `docs`, `src`, `captures`, and `README.md`: no matches for the protected password patterns. ## Implemented Surface - Public MXAccess method surface is accounted for: `Register`, `Unregister`, `AddItem`, `RemoveItem`, `Advise`, `UnAdvise`, `Write`, `WriteSecured`, `AuthenticateUser`, `ArchestrAUserToId`, `AddItem2`, `Write2`, `WriteSecured2`, `Suspend`, `Activate`, `AdviseSupervisory`, `AddBufferedItem`, and `SetBufferedUpdateInterval`. - Public event families are represented: `OnDataChange`, `OnWriteComplete`, `OperationComplete`, and `OnBufferedDataChange`. - `WriteSecured2` is implemented and live validated from .NET 10 x64 for the observed authenticated secured-write body shape. - `WriteSecured` remains intentionally unsupported because installed MXAccess returns `0x80004021` for the observed secured/verified paths before emitting a value-bearing NMX body. - Object/VARIANT timestamp overloads exist for `Write2` and `WriteSecured2`, matching the installed interop assembly's public API shape. - `SetHeartbeatSendInterval` is exposed and live validated through `MxNativeClient.Probe --probe-session-heartbeat --heartbeat-ticks=5 --heartbeat-max-missed=3`. - Explicit recovery is implemented as `MxNativeSession.RecoverConnection()` and `MxNativeCompatibilityServer.RecoverConnection(serverHandle)`. The probe `--probe-session-recover --tag=TestChildObject.TestInt --value=321` live validated subscribe, recover, preserved subscription count, and write-through against local NmxSvc. - `RecoverConnectionAsync` adds a caller-controlled retry loop via `MxNativeRecoveryPolicy`. Automatic write retry remains intentionally absent because it can duplicate writes. - Recovery lifecycle is observable through `RecoveryAttemptStarted`, `RecoveryAttemptFailed`, and `RecoveryCompleted` on both `MxNativeSession` and the managed compatibility facade. A live recovery probe with `--recover-attempts=2 --recover-delay-ms=100 --value=323` observed one started event, zero failed events, and one completed event. - Callback, operation-status, reference-registration, unparsed-callback, compatibility data-change, buffered-data-change, and write-complete payloads now carry `IsDuringRecovery`. The current policy is pass-through with an explicit marker rather than suppression or buffering. - `MxNativeClient.Probe --probe-session-recover-multi` replays several active subscriptions and counts recovery-window callbacks by callback family. ## Runtime Evidence Added In Latest Sprints - GR identified `TestMachine_001.TestHistoryValue` as a deployed, historized integer dynamic attribute. - Captures `121` and `122` proved context-bearing buffered registration/result bodies for `TestHistoryValue.property(buffer)` in context `TestMachine_001`. - Both supervisory and plain advise buffered captures still produced no native `Fire_OnBufferedDataChange` entry on this VM. - Reflection over `ArchestrA.MXAccess.dll` confirmed the 18-method public method surface, four event families, `MxStatus` layout, `MxStatusCategory`, `MxStatusSource`, and full `MxDataType` enum values. - Installed `Lmx.aaDCT` detail text has been folded into `MxStatusDetails` for details `16`-`61`, `541`, `542`, and `8017`. - Explicit recovery event reporting is implemented and live validated. The events report attempt number, maximum attempts, exception, and retry intent for failed attempts. - A live multi-subscription recovery probe replayed four subscriptions and preserved all four. It observed two data callbacks and four unparsed callbacks overall, but zero callbacks with `IsDuringRecovery=true` on this VM. - A follow-up churn run with `--recover-concurrent-writes` wrote `TestChildObject.TestInt` values `330`-`334` from a separate managed session during recovery. It preserved all four subscriptions and observed four data callbacks overall, including two with `IsDuringRecovery=true`. This validates the pass-through-with-marker callback policy under live traffic. - `aaMxDataConsumer.dll` was imported with `tlbimp` into `analysis\interop\Interop.aaMxDataConsumer.dll` and decompiled under `analysis\decompiled-interop\Interop.aaMxDataConsumer`. Registry CLSID `{85209FB2-0BA1-4594-BBC4-59D3DDAB823D}` maps to `MxDataConsumer Class`. - `MxDataConsumerProbe` can instantiate `DataConsumerClass`, register `IDataConsumerCallback`, resolve namespace strings to namespace ID `1`, and call `ResolveReference`, `subscribe`, `ActivateSuspend`, and `ProcessActivateSuspend2`. However, `IsConnected(namespaceId)` remains `0` for tested namespace strings (`Galaxy`, `ArchestrA`, `Lmx`, `localhost`, `ZB`), no registration/subscription responses are produced, and `ProcessActivateSuspend2` returns `0x8007139F` (`ERROR_INVALID_STATE`). - `DataClientClass` appears in the imported `aaMxDataConsumer` type library, but its CLSID `{73BC4121-FF89-4762-901C-206E2BD9FE87}` is not registered on this node; `MxDataConsumerProbe --probe-dataclient` reports `0x80040154` (`REGDB_E_CLASSNOTREG`) before endpoint tests can run. - Headless/ILSpy analysis of `aaMxDataConsumer.dll` shows the COM consumer is a mixed-mode wrapper around managed ASB data proxies. `CDataClientCLI` creates a `DataClientProxy`, stores the namespace string, starts an auto-connect worker, and `DataClientProxy.Initialize` passes that same string as `AccessName` to `IDataProxySelector.SelectProxyForLatestEndpoint`. - `ASBIDataV2Adapter.dll` from the GAC contains `IDataProxySelector`. It first calls `ASBDataV2Proxy.FindIDataEndpoint(accessName, DiscoveryScope.Global)`; if that returns endpoints it constructs `ASBDataV2Proxy`, otherwise it falls back to V1. The discovery scope is `domainname//global`. - `AsbProxyProbe` live x64 discovery found one `IASBIDataV2` endpoint for access name `ZB`: `net.tcp://desktop-6jl3kko/ASBService/Default_ZB_MxDataProvider/IDataV2`. It found no endpoint for `Default_ZB_MxDataProvider`, `Galaxy`, `localhost`, or `ZB2`. - `AsbProxyProbe --access=ZB --connect` opened the ASB data proxy from an x64 managed process. `ASBDataV2Proxy.Connect` returned `true`, channel state was `Opened`, and `PublishWriteComplete` returned `0x00000000` with no pending writes. This proves a managed x64 ASB route to LMX/NMX data services exists on this node. - `AsbProxyProbe --access=ZB --connect --register --read --tag=TestChildObject.TestInt` registered and read the test integer through `IASBIDataV2`. `RegisterItems` and `Read` both returned `0x00000000`; the item id was `18446462598732840961`; the read value was ASB `DataType.TypeInt32` (`4`) with payload `4E010000`, decoded as `334`. - `AsbProxyProbe --access=ZB --connect --register --read --write-int=401 --tag=TestChildObject.TestInt` accepted a basic ASB write and proved readback. The immediate `Write` result was globally successful, the per-item synchronous status was `0x0000001F` (`ArchestrAError.OperationWouldBlock`), the next read returned integer value `401`, and `PublishWriteComplete` then returned `0x00000020` (`ArchestrAError.PublishComplete`) with the original write handle `0xA5B20001` and per-item completion status `0x00000000`. This is the first direct evidence that ASB write completion polling can supply the missing operation-completion source without the unstable DataConsumer COM wrapper. - Forcing the x86 `MxDataConsumerProbe` to `--namespace=ZB` hung in the COM wrapper path and was stopped. The direct ASB route is currently the cleaner path for x64 managed implementation and for any future `OperationComplete` trigger testing. - The pure .NET 10 ASB port in `src\MxAsbClient` now proves the live data path without loading AVEVA assemblies. Key auth details recovered during the port: this VM's ASB solution registry key is `Archestra_DESKTOP-6JL3KKO`, `HashAlgorthim=None`, `keySize=256`, and the solution overrides the DH prime with the installed 768-bit value. The remaining compatibility fixes were the AVEVA CLR data-contract namespaces/field ordering for `ConnectionValidator`, `WriteValue`, `ItemStatus`, `ItemIdentity`, and `ItemWriteComplete`, plus mutable-struct-safe binary decode for nested `Variant` and `ASBStatus` values. - `MxAsbClient.Probe --tag=TestChildObject.TestInt --write-int=412` completed from .NET 10 x64. The run read the previous value `411`, accepted write `412` with immediate per-item `0x0000001F` (`OperationWouldBlock`), read back `412`, and decoded `PublishWriteComplete` result `0x00000020`, count `1`, handle `0xA5B21001`, and final per-item status `0x00000000`. - `RegisterItems` parity is resolved for the observed startup race. ASB `AuthenticateMe` is a one-way WCF call; the first immediate `RegisterItems` can arrive before `ASBIDataV2Shim.AuthenticateMe` adds the connection implementation. The client now matches installed proxy signing for normal data calls and retries `RegisterItems` briefly when the immediate result is `0x00000001` (`InvalidConnectionId`). Stage21 evidence shows first register message `2` returned `InvalidConnectionId`, retry message `3` returned `0x00000000` with item id `18446462598732840961`, and later calls on the same connection succeeded. - `UnregisterItems` is implemented in the pure .NET 10 ASB port and compared against the installed AVEVA `ASBDataV2Proxy`. Both clients return global success `0x00000000` and the same per-item `0x0000000B` (`OperationFailed`) for the registered `TestChildObject.TestInt` identity on this provider. Evidence: `analysis\proxy\mxasbclient-probe-stage23-unregister-id.txt` and `analysis\proxy\asbproxyprobe-unregister-compare.txt`. - Multi-item ASB register/read is implemented and live validated in the pure .NET 10 port. `analysis\proxy\mxasbclient-probe-stage24-multi-read.txt` registers and reads `TestChildObject.TestInt` and `TestMachine_001.TestHistoryValue` in single two-item requests. Both register and read return global `0x00000000` and per-item `0x00000000`; the read values decode as ASB `TypeInt32` with previews `412` and `303`. - The pure .NET 10 ASB port now has non-live ASB `Variant` construction and decode/display coverage for the core scalar and array type matrix: `TypeBool`, `TypeInt32`, `TypeFloat`, `TypeDouble`, `TypeString`, `TypeDateTime`, `TypeDuration`, and their matching array forms. The public client also exposes a generic `Write(tag, Variant, writeHandle)` path so the next live write probes can reuse the same encoder instead of being hard-coded to `Int32`. - A live ASB register/read probe validated the deployed scalar and array read type matrix from .NET 10 x64: `TestChildObject.TestBool` -> `TypeBool` (`17`), `TestChildObject.TestInt` -> `TypeInt32` (`4`), `TestChildObject.TestFloat` -> `TypeFloat` (`8`), `TestChildObject.TestDouble` -> `TypeDouble` (`9`), `TestChildObject.TestString` -> `TypeString` (`10`), `TestChildObject.TestDateTime` -> `TypeDateTime` (`11`), and the matching `TestBoolArray[]`, `TestIntArray[]`, `TestFloatArray[]`, `TestDoubleArray[]`, `TestStringArray[]`, and `TestDateTimeArray[]` returning ASB array types `57`, `44`, `48`, `49`, `50`, and `51`. All register/read per-item statuses were `0x00000000`, and previews decoded correctly. - `MxAsbClient.Probe` now keeps SOAP envelopes and custom serializer byte dumps opt-in through `--dump-messages`; normal traced runs still show stages, statuses, type IDs, payload lengths, timestamps, and decoded previews without dumping request/response bodies. - Pure .NET 10 ASB scalar writes are live validated beyond `Int32`: `TestBool` accepted a `TypeBool` write and later read back `False` then `True`; `TestFloat` wrote/read `13.25`; `TestDouble` wrote/read `13.75`; `TestString` accepted `asb-scalar-write` and read it back on a delayed follow-up read; `TestDateTime` wrote/read `2026-04-26T14:33:00Z`. These runs confirm the scalar factory payloads are accepted by the live provider. Immediate `PublishWriteComplete` often returned count `0`, and bool/string immediate readback could be stale or time out, so completion polling/readback timing remains part of the production timeout policy gap. - Pure .NET 10 ASB array writes are live validated for the deployed dynamic array tags. `TestIntArray[]` accepted/read back `11`-`20`; `TestBoolArray[]` accepted/read back alternating false/true values; `TestFloatArray[]` and `TestDoubleArray[]` accepted/read back `11.1`-`20.1`; `TestStringArray[]` accepted/read back `K11`-`T20`; and `TestDateTimeArray[]` accepted/read back ten UTC timestamps from `2026-04-26T14:40:00Z` through `2026-04-26T14:49:00Z`. Int, bool, and string array readback needed a delayed follow-up read, matching the scalar timing behavior noted above. - Production cleanup removed the active ASB build warnings: the vulnerable transitive `System.Security.Cryptography.Xml` `10.0.0` package is overridden with `10.0.7`, `dotnet list package --include-transitive --vulnerable` now reports no vulnerable packages for `MxAsbClient`, and the system-auth PBKDF2 derivation uses the non-obsolete static API while preserving the installed proxy's 1000-iteration SHA1 derivation inputs. A live ASB read of `TestChildObject.TestInt` still succeeds after the authenticator change. - Pure .NET 10 ASB subscription/publish is now live-proven for the basic lifecycle. `MxAsbClient.Probe --subscribe --publish-count=3` created subscription id `3`, added monitored items for `TestChildObject.TestInt` and `TestChildObject.TestString` with per-item status `0x00000000`, received both values on the second publish poll (`TypeInt32` preview `412` and `TypeString` preview `asb-scalar-write`), deleted the subscription with global success, and then completed the existing unregister cleanup path. Publish responses returned global `0x00000020`, matching the previously observed completion queue success signal, so exact result/status mapping remains open. - The ASB publish path now maps raw `MonitoredItemValue` responses into callback-ready values with item-id-to-tag-name resolution, decoded value, UTC timestamp, `MxQuality`, and parsed ASB status elements. A live publish run for `TestChildObject.TestInt` and `TestChildObject.TestString` decoded quality `0x00C0` and status elements `OpcUaStatus:0|OpcUaVendorStatus:0|MxStatusCategory:0|MxStatusDetail:0|MxQuality:192` for both values. The same run added `DeleteMonitoredItems`, returned global success and per-item `0x00000000` for both monitored identities, then deleted the subscription successfully. - `MxAsbDataClient` now exposes `PublishedValueReceived` plus `PublishValues`. `PublishValues` keeps the raw `PublishResponse`, maps values through the client's monitored-item id cache, and raises one event per mapped value. A live probe observed `published_event[0]` for `TestChildObject.TestInt` and `published_event[1]` for `TestChildObject.TestString`, both with quality `0x00C0` and expected previews. - `MxAsbCompatibilityServer` now adapts the pure ASB stream into an MXAccess-like server/item-handle data-change facade. A live `MxAsbClient.Probe --compat-subscribe --publish-count=3` run registered ASB server handle `1`, added/advised item handles `1` and `2`, polled publish, raised two `compat_data_change` events with values `412` and `asb-scalar-write`, quality `0x00C0`, decoded ASB status elements, removed both monitored items, and unregistered cleanly. - The compatibility facade now has an `Advise` overload that accepts `AsbSubscriptionOptions` plus `AsbMonitoredItemOptions`, matching the public ASB subscription shaping instead of forcing positional primitives. The probe compatibility subscribe path now exercises this route, and a live compatibility subscribe run through the options overload registered/advised item handles, published mapped `compat_data_change` events, removed monitored items, and unregistered cleanly. - Initial non-success ASB item-status mapping is implemented. A live probe for `DefinitelyMissingObject.DefinitelyMissingAttribute` showed global register and read success but per-item read error `0x000A` (`InvalidMonitoredItems`), an empty value with value-status payload decoded as `OpcUaStatus:32905|OpcUaVendorStatus:0|MxStatusCategory:750|MxStatusDetail:0|MxQuality:0`, and unregister per-item error `0x000B` (`OperationFailed`). Unknown payloads are still preserved rather than guessed. - `MxAsbClient.Probe --probe-error-cases` now keeps broader live ASB non-success evidence opt-in without changing production client behavior. Evidence in `analysis\proxy\mxasbclient-probe-error-cases-v2.txt` covers: invalid read target global success with per-item `0x000A` (`InvalidMonitoredItems`) plus bad value status; invalid-target async write immediate per-item `0x001F` (`OperationWouldBlock`) followed by `PublishWriteComplete` global `0x0020` (`PublishComplete`) and completion per-item `0x0006` (`MonitoredItemsNotFound`) with status payload `OpcUaStatus:6|OpcUaVendorStatus:0|MxStatusCategory:4|MxStatusDetail:6`; wrong-type string write to `TestChildObject.TestInt` immediate per-item `0x001F`, completion per-item `0x0013` (`WriteFailedBadTypeMismatch`) with status payload `OpcUaStatus:19|OpcUaVendorStatus:0|MxStatusCategory:4|MxStatusDetail:8001`, and unchanged readback value `412`; invalid monitored-item cleanup global success with per-item `0x000B` (`OperationFailed`); invalid subscription delete global `0x000C`, status `0x0020`, specific `0x80020000`; and empty subscription publish returning global `0x0020` with no values. - ASB result/status summaries now name the full installed `ArchestrAError` code set, classify publish `0x0020` (`PublishComplete`) as success-like for publish polling, summarize `MxQuality` as good/uncertain/bad/unknown, and map known MX status details `16` and `17` to `RequestTimedOut` and `BadNoCommunication` while preserving raw category/detail/quality values. - Async ASB write completion now has a production-oriented polling helper. `WaitForWriteComplete` polls `PublishWriteComplete` for a target write handle until completion or timeout, preserving every raw poll response and completion record. `WaitForWriteCompleteAndRead` adds optional delayed readback without retrying or duplicating the write. A live probe using `--write-int=412 --wait-write-complete --write-complete-timeout-ms=5000 --write-complete-poll-ms=250 --write-readback-delay-ms=500` saw the first completion poll return count `0`, the second poll return the matching handle `0xA5B21001`, and readback return `412`. - ASB client disposal now has explicit cleanup reporting. `Dispose()` delegates to idempotent `Cleanup()`, sends signed `Disconnect` best-effort, closes the channel and factory independently, aborts safely after close/fault failures, and records `LastCleanupResult` with `Completed`, `Succeeded`, `UsedAbortFallback`, and `RequiresNewConnection`. A live read probe ended with `asb.stage=cleanup`, `asb.stage=disconnect`, and `asb.cleanup.succeeded=True`. - ASB reconnect now has an explicit opt-in API. `MxAsbDataClient.Reconnect` validates caller retry options, optionally cleans up the current connection, returns a new client on success, and preserves attempt plus cleanup evidence without silently replaying reads or writes. A live `MxAsbClient.Probe --probe-reconnect --reconnect-attempts=2 --reconnect-delay-ms=250 --cleanup-disconnect-timeout-ms=5000 --cleanup-close-timeout-ms=5000` run read `TestChildObject.TestInt` as `412`, cleaned up and disconnected the original connection with caller cleanup timeouts, connected successfully on attempt `1`, re-registered the tag on the new client, read back `412`, and completed final cleanup successfully. - ASB cleanup partial-failure behavior is now covered in focused local tests without forcing live provider faults. The close-or-abort policy is factored into `AsbCommunicationCleanup`, and tests cover already-closed objects, faulted objects that skip close and abort directly, close failure followed by abort fallback, abort failure reporting, and propagation of the configured close timeout. - ASB cleanup cancellation now has explicit policy. `AsbClientCleanupOptions` accepts a `CancellationToken`; when cancellation is already requested, cleanup skips graceful disconnect/close attempts and uses local abort cleanup for non-closed channel/factory objects. Existing disconnect and close timeouts still bound synchronous WCF calls that have already started. A live `MxAsbClient.Probe --probe-canceled-cleanup` run connected, registered, and read `TestChildObject.TestInt` as `412`, then skipped disconnect and aborted both opened communication objects locally. The cleanup result completed with `succeeded=False`, `abort=True`, `requires_new=True`, and an `OperationCanceledException` disconnect marker. - Safe connection-failure evidence is now captured without destabilizing the live ASB provider. `MxAsbClient.Probe --probe-connect-failure --endpoint=net.tcp://localhost:1/ASBService/Default_ZB_MxDataProvider/IDataV2` reports `connect_failure_observed=True`, an `EndpointNotFoundException`, and inner `SocketException` `10061` for a refused local TCP endpoint. `Connect` now also closes or aborts any WCF channel/factory objects created before a connection setup failure; the refused-endpoint probe reports `asb.stage=connect-cleanup` before surfacing the exception. - OperationComplete candidate evidence was narrowed on the direct ASB route. The `IASBIDataV2` contract exposed by the live endpoint has no activate, suspend, or generic operation-complete operation; only `PublishWriteComplete` exists, and it is write-specific. A live `MxAsbClient.Probe --probe-operation-complete-candidates` run against `TestChildObject.TestInt` and `TestChildObject.TestString` polled `PublishWriteComplete` before and after create-subscription, add-monitored, publish, delete-monitored, and delete-subscription operations. Every poll returned count `0`, while the non-write operations themselves succeeded. - ASB buffered-subscription probing is now explicit. `MxAsbDataClient` exposes the `MonitoredItem.Buffered` flag through `AddMonitoredItems`, and `MxAsbClient.Probe --subscribe-buffered` sets it. A live buffered ASB publish probe against the historized `TestMachine_001.TestHistoryValue` succeeded, but returned the same single current `MonitoredItemValue` shape as the normal publish path: value `303`, quality `0x00C0`, timestamp `2026-04-26T02:33:45.4260000Z`, and no multi-sample buffered batch. - ASB status mapping now includes installed MX detail `33` (`WriteAccessDenied`) and maps it to `WriteFailedAccessDenied`. Tests cover success, invalid monitored item, wrong-type write completion, invalid cleanup evidence inputs, request timeout detail `16`, platform/no-communication detail `17`, and access-denied detail `33`. - Safe access-denied/no-communication candidate probes did not produce those source conditions on this VM. Same-value direct ASB writes to secured `TestMachine_001.ProtectedValue` and verified `TestMachine_001.ProtectedValue1` both completed successfully and read back unchanged, so direct system-auth ASB writes do not reproduce the MXAccess public secured-write rejection path here. A read-only sweep of `TestMachine_001.ProtectedValue` through `TestMachine_020.ProtectedValue` registered and read all 20 values with good quality `0x00C0`; no no-communication status was observed. - Native NMX completion-only operation-status handling is now stricter. One-byte completion-only frames remain preserved as raw, unpromoted completion statuses even when the byte is `0x00`; 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. Tests cover completion-only `0x00`, `0x41`, and `0xEF`, plus the promoted `0x8050/0x00` status-word frame. A search of the available Ghidra/decompiled outputs did not expose a completion-byte-to-`MXSTATUS_PROXY[]` mapping table beyond this public-event evidence. - Public ASB connection shaping has started. `AsbConnectionOptions` is now the stable options object for `MxAsbDataClient.Connect`, the previous string overload delegates to it, and `MxAsbCompatibilityServer.Register` has a matching options overload. Endpoint validation now happens before registry or WCF setup work. `AsbPayloadDebug` is no longer part of the public surface and is friend-only for the test/probe assemblies. A clean Release probe build, non-live ASB contract test run, and live read of `TestChildObject.TestInt` all passed after this change. - ASB write-completion options now validate their own polling/readback policy and expose a `CancellationToken`. Cancellation is checked before each `PublishWriteComplete` poll and during poll/readback delays; already-running synchronous ASB calls remain bounded by the existing WCF operation behavior. A live same-value write-completion probe still completed on the second poll for handle `0xA5B21001` and read back `412`. - ASB subscription API shaping now has `AsbSubscriptionOptions` and `AsbMonitoredItemOptions` overloads while preserving the existing positional overloads. A live subscribe/publish probe created subscription `15`, added monitored items for `TestChildObject.TestInt` and `TestChildObject.TestString`, published both mapped values/events, deleted the monitored items, deleted the subscription, and cleaned up the ASB connection successfully. - `AsbPublishResult` now exposes a derived `Result` summary and `HasValues` helper so callers do not have to remap raw `PublishResponse.Result` on every publish poll. The existing raw response and mapped values remain preserved. - Public API/request-shaping tests were expanded without live ASB dependency. They now pin defaults, validation, overload visibility, and helper DTO shape for connection, write completion/readback, subscription, monitored-item, compatibility `Advise`, and publish-result surfaces. - Basic writes now also have an `AsbWriteOptions` overload carrying the write handle and optional comment. The existing positional write overload and `WriteInt32` path delegate through it, preserving behavior; a live same-value write-completion probe still completed on the second poll and read back `412`. - Public multi-item APIs now explicitly reject null collection arguments before touching client state: `RegisterMany`, `UnregisterMany`, `ReadMany`, option-based `AddMonitoredItems`, and `DeleteMonitoredItems`. Empty collections and tag/item contents keep their prior behavior. - Published values and compatibility data-change events now expose derived `StatusSummary` helpers, and `AsbResultMapper.ToItemSummaries` maps nullable item-status arrays into raw-preserving summaries with null/empty as an empty result. - `docs\ASB-Variant-Wire-Format.md` now captures the supported ASB `Variant` wire format: type IDs, scalar and array payload layouts, timestamp/duration handling, string encoding, runtime value wrapping, quality/status payload parsing, and intentionally raw-preserved unsupported types. - `docs\ASB-Native-Integration-Decision.md` now records the recommended integration boundary: prefer `MxAsbClient` for the regular tag data plane behind a higher-level compatibility routing facade, keep `MxNativeClient` for native callback-only semantics and not-yet-proven MXAccess behaviors, and avoid merging ASB WCF lifecycle internals into the NMX DCE/RPC session. ## Remaining Highest-Value Gaps 1. Additional live faulted-channel and source-condition evidence that can be gathered safely. Current safe secured/verified-write and protected-value read sweeps did not produce access-denied or no-communication statuses. 2. Broaden pure .NET 10 ASB only where safe source conditions expose new behavior. Local ASB `Variant` encode/decode, live reads/writes, subscription/create/add/publish/delete-monitored/delete-subscription, mapped publish events, compatibility data-change facade, options-shaped connection/write/subscription/advise/write-completion APIs, cleanup, and reconnect are now covered. Remaining work is mainly external failure modes such as access denied or no-communication when a safe source condition is available. 3. A native runtime trigger for `OperationComplete`. The direct ASB path now proves a write-completion queue (`PublishWriteComplete`) carrying write handles and per-item statuses. Direct `IASBIDataV2` does not expose activate/suspend or a generic operation-complete contract, and subscription create/add/publish/delete operations did not enqueue write-completion records. Map to MXAccess event ID `3` only if a separate native trigger is found. 4. A native runtime/source condition that emits `OnBufferedDataChange` sample batches. Direct ASB buffered monitored items are accepted by this provider, but the observed publish response still carries one current value rather than a native MXAccess buffered sample batch. 5. Exact mapping for completion-only operation-status bytes into `MXSTATUS_PROXY[]`; current code now preserves all completion-only bytes as unpromoted raw statuses instead of guessing, including completion-only `0x00`. 6. Cleanup behavior around live faulted/partial failure cases when a safe provider condition is available. 7. Less-common ASB variant types only when real deployed tags expose them; the currently supported/proven variant layout is documented and unsupported declared types remain raw-preserved. ## Recommended Next Sprint Treat the public ASB API-shaping sprint as closed unless a concrete caller gap appears. The remaining local documentation gaps are also closed. Return to exact completion-only operation-status mapping into `MXSTATUS_PROXY[]` only if a new safe native public-event capture or deeper targeted decompile can provide evidence. Keep live faulted-channel, access-denied, and source no-communication probes opportunistic unless a safe provider condition appears.