Ab.Transport.Tests: predecessor-wait counter instead of 300 ms (DeviceSessionPoolTests x2), throttle
queue/interval-park hooks instead of 50/100 ms (ForwardOpenThrottleTests x2), UnobservedTaskProbe with a
must-report control fault instead of N GC cycles (EncapsulationClientTests), re-armed keep-alive timer as
the control for the never-opened keep-alive test.
AbCip.Tests: still-polling sibling / control driver read counts instead of 300-500 ms (subscriptions x4,
alarm projection x5), structural ProbeTask==null + enabled-probe control (host probe x2), predecessor
wait (NativeAbCipLeaseReleaseTests), processed waits in the shutdown/logging tests.
AbLegacy.Tests: sibling-subscription control (Unsubscribe_halts_polling), ProbeCts==null + control.
AbCip.IntegrationTests differential safety: a post-phase control open through the same throttle instead
of 1.5-2.5 s sleeps (via a native tag init, keeping the harness read-only guard green).
Fake tag ReadCount made interlocked; CapturingLogger entries snapshotted under a lock.
Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
- Process-wide CipConnection statics (ForwardOpenCount, Forward Close counts, RequestsSent, exchange
stats, OpenAttempts, OpenAttemptBudget) move to an instance ConnectionDiagnostics owned by each
DeviceSessionPool (and by a stand-alone CipConnection). The open-attempt budget becomes a disposable
per-DeviceKey limit (LimitOpenAttempts); the differential harness scopes one to the press under test.
- LibplctagOrphanRelease.ForceRootingForTest is gone: ReleaseIfOrphaned(tag, canReadHandles) overload.
- A connected reply with general 0x01 / extended 0x0107 or 0x0203 (target no longer holds the class-3
connection, TCP still up) retires the session at once; the next send reopens through the throttle.
- New tests: dispose during RegisterSession, abandoned-open observer (falsified), scheduler-dispose-throws
guard (DeviceSessionPool.CloseAsync), release-in-background with a shared open in flight, per-device
limit scoping, CIP-close recycle (request + keep-alive + negative control).
Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe