The bit write read and wrote the parent word as a 32-bit UDInt with no parent
check: a bit beyond a 16-bit parent was written into neighbouring bytes, and a
signed parent with its sign bit set read back >= 2^31, so the checked
conversion turned any bit write into BadOutOfRange.
The write now goes through ITwinCATClient.WriteBitAsync: the ADS client
resolves the parent symbol, checks the bit against it (TwinCATBitAccess.
CheckParent, as the notification path already did), reads exactly
parent.ByteSize raw bytes, flips one bit (TwinCATBitAccess.ApplyBitWrite) and
writes the bytes back by index group/offset or variable handle. A bit beyond
the parent is BadOutOfRange, a non-integer parent BadTypeMismatch, a short
parent read BadCommunicationError (never written back), all without a health
write. The per-parent RMW lock stays in the driver.
Refs #739
Claude-Session: https://claude.ai/code/session_01Ub9hGmYLQvn9XETzw7CMsT
A native notification for MAIN.Flags.3 / .ADSSTATE_RUN.0 was registered on the
literal WORD.N path, which ADS has no symbol for: live on the TC 2.11 Elma
cleaner Z33856 it failed with DeviceSymbolNotFound, and that registration
error tore down the whole subscribe call. The read path already reads the
parent word; the notification now does the same - it registers the parent as
raw bytes at its resolved width and reads the bit (TwinCATBitAccess), refusing
a bit outside the parent or a non-integer parent with BadTypeMismatch.