fix(sessions): scope ambient transcript watermark to session id#99385
Merged
Conversation
Ambient transcript watermarks now carry the transcript session id, resolve only for the current session entry, and skip stale room-event hooks that no longer match the prepared transcript session. This protects Telegram group prompt windows after reset by backfilling rows that are no longer present in the new session transcript, while preserving steady-state watermark filtering within one session. Fixes #99373 Release-note: fixes Telegram group context loss after session reset when ambient transcript watermarks outlived the transcript they referenced.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What Problem This Solves
Fixes #99373. The ambient transcript watermark (#99306) survives session resets, but the transcript rows it vouches for do not: after any reset (manual, daily, delete), every prompt-facing window consumer kept filtering out messages at/before the watermark while those rows existed only in the archived transcript. Confirmed in production: a new session's transcript began exactly at watermark+1, with all older group messages permanently invisible — not in the window, not in the transcript, never compactable.
Why This Change Was Made
Watermark validity is a fact about a specific transcript (sessionId), not about the chat. The fix makes that structural:
AmbientTranscriptWatermarknow carriessessionId; writes stamp the entry's current sessionId.readAmbientTranscriptWatermark) treat a watermark whose sessionId differs from the entry's current sessionId as absent — self-invalidating on every reset path, with no per-reset-flow cleanup to forget. Legacy records without sessionId are ignored the same way (cache-like state: window backfills once; no doctor migration).onMessagePersistedhook passes the prepared session id asexpectedSessionId; if the session reset between the durable row write and the watermark advance, the advance is skipped instead of stamping a transcript that lacks the rows.All consumers go through the read helper (Telegram session/prompt-context, live cache window, recovered threads, plugin-SDK facade), so they inherit the fix with no per-consumer changes.
User Impact
Ambient-mode group deployments no longer silently lose chat visibility across session resets: after a reset, the per-turn window backfills the persisted-but-archived messages (up to
historyLimit) instead of hiding them forever. Steady-state dedupe behavior within a session is unchanged.Evidence
extensions/telegram/src/bot-message-context.prompt-context.test.ts); core read/write/legacy/stale-hook coverage insrc/config/sessions/ambient-transcript-watermark.test.ts. Both fail-confirmed against the unfixed code (window collapsed to the unpersisted gap; legacy watermark still honored).node scripts/run-vitest.mjson touched tests,pnpm tsgo,pnpm check:test-types: exit 0.check:changedon the rebased branch: exit 0 (runtbx_01kwk866aemnttw2zjzgb8v8ek).Diagnosis side-finding recorded on the issue: the observed intra-day daily reset is explained by process-UTC +
DEFAULT_RESET_AT_HOUR=4semantics (sessionStartedAt < resolveDailyResetAtMs), not a reset-policy bug.