← Back to PRs

#22887: Preserve daily reset timestamps for inbound session metadata updates

by graysurf open 2026-02-21 19:53 View on GitHub →
size: S
# Preserve daily reset timestamps for inbound session metadata updates Closes #21161. ## Summary Fixes a session reset regression where inbound metadata/route writes refreshed `updatedAt` before `initSessionState` freshness checks. This caused group/channel sessions to appear perpetually fresh and skip daily reset boundaries. ## Problem - Expected: Group/channel sessions reset after the daily boundary (default 4am) when the previous activity was before the boundary. - Actual: Pre-reply inbound metadata writes updated `updatedAt` to `Date.now()`, so freshness checks always saw a fresh session. - Impact: Medium. Group/channel sessions could persist across daily reset boundaries, accumulating stale context. ## Reproduction 1. Use default session config (`session: null`). 2. Send messages in a group/channel session (for example Discord channel). 3. Wait until after the daily reset boundary (4am local). 4. Send a new inbound message in that same session. - Expected result: A new session is created after the boundary. - Actual result: The existing session ID is reused because `updatedAt` was refreshed by inbound metadata updates. ## Issues Found Severity: medium Confidence: high Status: fixed | ID | Severity | Confidence | Area | Summary | Evidence | Status | | --- | --- | --- | --- | --- | --- | --- | | PR-22887-BUG-01 | medium | high | `src/config/sessions/store.ts`, `src/channels/session.ts` | Inbound metadata/route updates advanced `updatedAt` before freshness evaluation, blocking daily reset. | `recordSessionMetaFromInbound` / `updateLastRoute` behavior before `initSessionState` | fixed | ## Fix Approach - Preserve `updatedAt` for existing entries in `recordSessionMetaFromInbound` so metadata-only patches do not refresh freshness timestamps. - Added `preserveUpdatedAt` option to `updateLastRoute` and used it in `recordInboundSession` (pre-reply inbound path). - Added regression tests that verify both metadata and route updates can preserve `updatedAt` while still updating routing/meta fields. ## Testing - `pnpm test -- src/config/sessions.test.ts` (pass) - `pnpm test -- src/auto-reply/reply/session.test.ts` (pass) ## Risk / Notes - Default `updateLastRoute` behavior remains unchanged; preservation is opt-in for inbound pre-reply writes. - This change is scoped to timestamp handling for freshness and does not alter routing key resolution. <!-- greptile_comment --> <h3>Greptile Summary</h3> This PR correctly fixes a session reset regression where inbound metadata writes were refreshing `updatedAt` timestamps before freshness evaluation, preventing daily reset boundaries from working properly for group/channel sessions. **Changes:** - `recordSessionMetaFromInbound` now preserves existing `updatedAt` timestamps (src/config/sessions/store.ts:851-855) - `updateLastRoute` accepts optional `preserveUpdatedAt` parameter for inbound pre-reply path (src/config/sessions/store.ts:873, 925-928, 941-943) - `recordInboundSession` uses `preserveUpdatedAt: true` when updating routes (src/channels/session.ts:52) - Added regression tests verifying timestamp preservation for both metadata and route updates (src/config/sessions.test.ts:244-322) **How it works:** The fix ensures metadata-only updates don't advance the freshness timestamp used by `evaluateSessionFreshness` (checks `updatedAt < dailyResetAt` at src/config/sessions/reset.ts:152). By preserving the original `updatedAt`, sessions correctly appear stale after crossing the daily reset boundary. **Implementation note:** Both functions use a post-merge timestamp correction (after `mergeSessionEntry` overwrites with `Date.now()`) rather than preventing the overwrite. This works correctly but involves redundant operations. <h3>Confidence Score: 5/5</h3> - Safe to merge - fix is well-tested with clear regression coverage and preserves backward compatibility - Fix correctly addresses the root cause by preserving timestamps during metadata-only updates. Implementation is conservative (opt-in via `preserveUpdatedAt` flag), thoroughly tested with two new regression tests covering both code paths, and default behavior remains unchanged. Only minor style improvement suggested (unreachable fallback code). - No files require special attention <sub>Last reviewed commit: 4fb541f</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs