Skip to content

fix: store timestamps in UTC so recall expiry filtering is order-correct - #11

Merged
krishna3554 merged 3 commits into
mainfrom
fix/recall-utc-expiry-normalization
Aug 27, 2026
Merged

krishna3554 merged 3 commits into
mainfrom
fix/recall-utc-expiry-normalization

Conversation

@krishna3554

@krishna3554 krishna3554 commented Aug 26, 2026

Copy link
Copy Markdown
Owner

Problem

Part of #9 (item 2).

Recall filters expired memories inside SQL by comparing ISO strings lexicographically:

(m.expires_at IS NULL OR m.expires_at > ?)

But records stored whatever UTC offset the client sent (isoformat() is not normalized). When a non-UTC offset shifts the wall-clock date across the UTC date boundary, comparison breaks.

Reproduced on main: memory with expires_at = 2026-08-27T10:00:00-11:00 (= 21:00Z, still valid at 20:00Z):

  • GET /v1/memories → status active (parsed-datetime comparison)
  • POST /v1/memories/recall0 results ("...T10:00:00-11:00" < "...T20:00:00+00:00" lexically)

The same memory is simultaneously visible in list and invisible in recall.

Fix

Add SQLiteMemoryRepository._utc_isoformat() and use it for every timestamp persisted into SQL-comparable columns (created_at, updated_at, expires_at on both insert and semantic-duplicate update paths) plus the recall now parameter and cursor encoding. All stored timestamps now share a fixed +00:00 offset, so lexicographic order equals chronological order. Read paths are unchanged — fromisoformat handles both.

Tests

  • test_recall_includes_memories_expiring_after_now_regardless_of_offset — repository-level regression test using a fixed clock and a -11:00 expiry one hour before cutoff
11 passed   # services/dma-api/tests

Open in Devin Review

Recall filters expiries inside SQL by comparing ISO strings
lexicographically, but records stored whatever UTC offset the client
sent. When the local wall-clock date crossed a date boundary relative to
UTC, still-valid memories were treated as expired and silently dropped,
while list/status reported them as active.

Normalise created_at/updated_at/expires_at (and the recall 'now'
parameter) to +00:00 on write so string comparison matches chronological
order. Cursor encoding uses the same normalisation for consistency.

Fixes part of #9
Copilot AI lite review requested due to automatic review settings August 26, 2026 08:46

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@vercel

vercel Bot commented Aug 26, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
project-49zal Ready Ready Preview Aug 27, 2026 3:22pm

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 1 additional finding.

Open in Devin Review

Co-authored-by: krishna3554 <87197325+krishna3554@users.noreply.github.com>
@krishna3554
krishna3554 merged commit 98c745f into main Aug 27, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants