fix(mtconnect): generation guard on the pump's cursor publish, chunks and re-baseline (R06:T-1)

A pump the lifecycle retired or abandoned that finished after the restart
installed the new session published its stale cursor onto it (PublishAgentCursor
only checked for a null or identical session), so the next pump read its first
chunk as an Agent restart: index cleared, a Bad flicker on every subscribed tag,
a needless re-baseline. The pump now carries the session generation it was
started against; the cursor publish is checked under _subscriptionLock (where the
session install and generation bump are atomic) and a superseded pump also stops
folding late chunks / re-baselines into the new session's index.

Refs #743

Claude-Session: https://claude.ai/code/session_01Ub9hGmYLQvn9XETzw7CMsT
This commit is contained in:
Joseph Doherty
2026-10-22 15:36:24 -04:00
parent fcdc44f9f7
commit 77bfadbdda
3 changed files with 178 additions and 16 deletions
+7
View File
@@ -324,6 +324,13 @@ the two need disambiguating, not just OR-ing together). On a changed
`/hosts` page — see [Known limitations](#known-limitations) for what that does
and does not do.
**A pump carries the session generation it was started against (review 2026-10-21 T-1).** A lifecycle restart
retires the running pump (or abandons it after its bounded teardown wait); if that pump finishes after the new
session is installed, its cursor publish, a late chunk and a late re-baseline are all dropped — checked under the
same lock the new session is installed and the generation bumped under. It used to land the OLD Agent's
`instanceId` + sequence on the new session, so the next pump read its first chunk as an Agent restart (index
cleared, one Bad flicker on every subscribed tag, a needless re-baseline).
## Write-back — observation injection, off by default
> ⚠️ **A write sets what the Agent *reports*, not what the machine does.** The value