V1 release prep per M6 DoD bullet 6: **`CHANGELOG.md`** — V1 release notes covering all 9 workspace crates (`mxaccess-codec`, `mxaccess-rpc`, `mxaccess-asb-nettcp`, `mxaccess-asb`, `mxaccess-galaxy`, `mxaccess-callback`, `mxaccess-nmx`, `mxaccess`, `mxaccess-compat`), the M0 → M6 milestone closeouts, deliberate divergences from the .NET reference (multi-record DataUpdate codec relaxation per F44; buffered single- sample stream per R2), and known limitations (F3 cross-domain NTLM, F45 buffered recovery replay, F46 Suspend/Activate wire instrumentation, R3/R4 OperationComplete trigger). Documents the dependency-ordered publish sequence (leaf crates first; dependent crates require their deps to exist on crates.io before their dry-runs can run). **`cargo publish --dry-run` validation:** - Leaf crates (mxaccess-codec, mxaccess-rpc, mxaccess-asb-nettcp): dry-run passes — tarball builds, metadata complete, license/ description/repository/rust-version all present via `workspace.package`. - Dependent crates (mxaccess-asb, mxaccess-galaxy, mxaccess-callback, mxaccess-nmx, mxaccess, mxaccess-compat): dry-run fails with "no matching package" against crates.io — expected behaviour, the registry lookup happens even with `--no-verify`. Validation of these crates falls to the build-test-clippy-public_api matrix rather than dry-run. `design/followups.md`: F43 moved to Resolved with a verdict pointing at this commit + the CHANGELOG. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5.8 KiB
Changelog
All notable changes to the mxaccess workspace are documented here. The
format follows Keep a Changelog;
the workspace as a whole follows SemVer but the
0.0.x line is pre-release / API-unstable.
[Unreleased] — V1 — 2026-05-06
V1 is the first publishable cut. Closes M0 → M6 from
design/60-roadmap.md.
Added
mxaccess-codec— pure protocol codec coveringMxReferenceHandle,NmxTransferEnvelope,NmxItemControlMessage,NmxWriteMessage(scalar- array, normal + timestamped),
NmxSecuredWrite2Message,NmxSubscriptionMessage(single + multi-record DataUpdate per F44),NmxReferenceRegistrationMessage,NmxMetadataQueryMessage,NmxOperationStatusMessage,ObservedWriteBodyTemplate, ASB Variant +AsbStatus+RuntimeValue,MxStatus,MxValueKind,MxDataType,MxValue. Counting-allocator bench harness inbenches/alloc_count.rs(F38) reports 1–4 allocs per write across the proven matrix, well under the R12 < 5/write target.
- array, normal + timestamped),
mxaccess-rpc— DCE/RPC PDU codec, NTLMv2 client + server-direction packet-integrity verify (F2 withsubtle::ConstantTimeEq), TCP transport, OBJREF parser + Win32CoMarshalInterfaceemitter (F6),IObjectExporter::ResolveOxid+ResolveOxid2(F10),IRemUnknown::RemQueryInterface+RemAddRef/RemRelease(F11).mxaccess-callback— RPC server hostingINmxSvcCallback+IRemUnknownfor inboundDataReceived/StatusReceivedframes.mxaccess-nmx—INmxService2client (RegisterEngine2,TransferData,AddSubscriberEngine,SetHeartbeatSendInterval, etc.) plus auto-resolvingNmxClient::createfactory (F12, gated bywindows-com).mxaccess-galaxy—tiberius-backedResolver+UserResolver(F14, gated bygalaxy-resolver).mxaccess-asb-nettcp—[MS-NMF]framing +[MC-NBFX]binary-XML[MC-NBFS]static dictionary + DH/HMAC/AES auth crypto with constant-timemod_expviacrypto-bigint::DynResidue(F27).
mxaccess-asb—IASBIDataV2client (Connect,RegisterItems,Read,Write,PublishWriteComplete,CreateSubscription,AddMonitoredItems,Publish,DeleteMonitoredItems,DeleteSubscription,Disconnect) with canonical-XML HMAC signing for all 13ConnectedRequestshapes (F28) and DataContract field-suffix names on the binaryMonitoredItembody (F34).mxaccess— async Tokio façade exposingSession,AsbSession,Subscription(Stream<Item = Result<DataChange, Error>>),subscribe_bufferedper R2 single-sample-with-cadence-knob semantics (F36),recover_connectionreconnect loop (F16), recovery events (RecoveryEvent::Started/Recovered/Failed), and a typedErrortaxonomy. Optionalmetricsfeature emits per-op counters, latency histograms, and connection-state gauges (F40).mxaccess-compat—LMXProxyServer-shaped Rust facade exposing the 18-methodILMXProxyServer5surface as async fns overmxaccess::Session/AsbSessionwith aMutex<HashMap<i32, ItemRef>>handle table andStream-based event channels (F35).- Examples —
connect-write-read.rs,subscribe.rs,subscribe-buffered.rs,asb-subscribe.rs,multi-tag.rs,recovery.rs,secured-write.rs, plus diagnosticasb-relay.rs. Live-probe DoD verified end-to-end against the AVEVA install. - Tooling —
cargo public-apibaselines underdesign/public-api/{crate}.txtwith CI drift check (F41).design/M6-bench-baseline.mdrecords the alloc-count baseline.
Changed (vs the .NET reference)
NmxSubscriptionMessage::parse_data_updateacceptsrecord_count >= 1; the .NET reference hard-throws onrecord_count != 1. F44 evidence walk againstcaptures/094-frida-buffered-separate-writer/documents the multi-record observation that drove the divergence.subscribe_bufferedreturns aStream<Item = DataChange>(single-sample-per-event); per R2 verification the cadence is a server-side delivery rate knob, not a multi-sample payload.
Known limitations
- F3 — cross-domain NTLM Type1/2/3 fixture is permanently out-of-scope on the dev host (single-domain). Single-domain wire parity is verified; cross-domain is documented but not regression- tested.
- F45 — recovery replay for buffered subscriptions falls through
to plain
AdviseSupervisory, losing the.property(buffer)registration. Filed as a follow-up. - F46 —
LmxProxy.dll!CLMXProxyServer.Suspend/.Activatewire emission was not instrumented; the compatibility-server's client-side gating is documented but the underlying ORPC call shape is unconfirmed. - R3 / R4 —
OperationCompletetrigger conditions and completion-only byte mappings are unmapped in both the .NET reference and the Rust port. Frame bytes are preserved verbatim viaSession::operation_status_events().
Publish order
Workspace crates form a dependency DAG; cargo publish requires
already-published deps to exist on crates.io, so the order matters.
For V1 cut:
mxaccess-codec(no internal deps)mxaccess-rpc(no internal deps)mxaccess-asb-nettcp(no internal deps)mxaccess-galaxy(depends on codec)mxaccess-callback(depends on rpc + codec)mxaccess-asb(depends on codec + asb-nettcp)mxaccess-nmx(depends on codec + galaxy + rpc + callback)mxaccess(depends on all the above)mxaccess-compat(depends on mxaccess)
cargo publish --dry-run validates each crate's metadata + tarball
in isolation; the dependent crates' dry-runs require the leaf crates
to actually exist on crates.io (the registry lookup happens regardless
of --no-verify). For pre-publish verification: leaf crates dry-run
in CI; dependent crates are validated by the public-api baseline +
build-test-clippy matrix.