I1: a live verdict no longer waives the value check. Only elements that moved between the two libplctag reads are excused.
- An element equal in both libplctag reads must also be equal through native; otherwise **NO: stable element i**.
- A moved element must not read NaN or infinity on native unless libplctag saw it too; otherwise **NO: non-finite element i**.
- Live tags log their full raw bytes and every element, and the summary reports live tags as N of the total.
- The offline pin adds the pass-1 Real[5] shape: a stable element shifted on native fails. It is red with the element check disabled.
M9: after each native phase (differential and latency), wait for the session close. With AB_DIFF_COUNT_OPENS=1, assert exactly one Forward Close was sent, using the new CipConnection counters; acked is logged.
M8: each latency pass logs its GC collection deltas (gen0/1/2) for both transports, plus native per-exchange round-trip min/mean/max.
M4: the latency test also asserts that no libplctag orphan had to be rooted.
Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
In T21 press pass 1, two REAL tags diverged only because their live values moved
between the sequential libplctag and native phases (WW_M4ActualTemp 384.887 ->
385.138).
The libplctag phase now reads every selected tag a second time, paced, before
native starts (TransportObservations.ProbeReads). A tag whose two libplctag reads
both succeed and differ is classed live. For a live tag, parity still requires:
- the same status (and the native-TypeMismatch rule);
- no decode error;
- the same raw length;
- the same CIP type code when both sides expose one (native records it now;
libplctag.NET 1.5.2 does not);
- the same decoded shape.
Value equality is not required. Live tags get their own list and a "libplctag
probe" table column, and are counted as neither expected nor unexpected
divergences.
A tag that reads stable on libplctag but differs on native is still an unexpected
divergence, and a missing or failed probe never makes a tag live. The offline pin
A_live_value_is_compared_structurally_and_a_stable_one_by_value goes red with the
live branch disabled.
Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe