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

233 lines
13 KiB
Markdown

# 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:
```text
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.
6. 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.
7. 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.
8. 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.