Skip to content

feat(memory): add expiry, supersession, and TTL support#84

Merged
Siddhant-K-code merged 1 commit into
mainfrom
feat/memory-expiry-supersession
May 9, 2026
Merged

feat(memory): add expiry, supersession, and TTL support#84
Siddhant-K-code merged 1 commit into
mainfrom
feat/memory-expiry-supersession

Conversation

@Siddhant-K-code
Copy link
Copy Markdown
Owner

What

Adds the ability to mark memory entries as expired or superseded, with TTL support on write.

Why

Memory that can't be pruned becomes noise. When a decision is reversed or information becomes outdated, there was no way to mark it — stale entries degraded retrieval quality over time.

Changes

Core (pkg/memory)

  • Expire() — marks entries as expired; they remain in the store but are excluded from Recall by default
  • Supersede() — marks an entry as expired and stores a forward pointer to its replacement
  • StoreEntry.ExpiresAt — optional TTL; entries past their expiry time are filtered at query time
  • RecallRequest.IncludeExpired — opt-in flag to retrieve expired entries
  • Stats now reports expired_count and active_count
  • Dedup skips expired entries so replacements aren't silently merged
  • EventExpired lifecycle event for cache boundary managers

API

  • POST /v1/memory/expire — expire entries by ID
  • POST /v1/memory/supersede — supersede one entry with another

MCP

  • memory_expire tool
  • memory_supersede tool

Tests

  • 12 new tests: expire, double-expire, supersede, supersede-not-found, supersede-already-expired, lifecycle events, TTL past/future, stats with expired count, dedup-skips-expired, empty request, empty old_id

Usage

# Expire an entry
curl -X POST localhost:8080/v1/memory/expire \
  -d '{"ids": ["abc123"]}'

# Supersede: old decision replaced by new one
curl -X POST localhost:8080/v1/memory/supersede \
  -d '{"old_id": "abc123", "new_id": "def456"}'

# Store with TTL (auto-expires after 24h)
curl -X POST localhost:8080/v1/memory/store \
  -d '{"entries": [{"text": "temp context", "expires_at": "2026-05-10T00:00:00Z"}]}'

# Recall includes expired entries when needed
curl -X POST localhost:8080/v1/memory/recall \
  -d '{"query": "old decisions", "include_expired": true}'

Closes #79

- Add Expire() and Supersede() methods to the memory Store interface
- Expired entries excluded from Recall by default (IncludeExpired flag to override)
- Superseded entries store a forward pointer to the replacement
- StoreEntry accepts ExpiresAt for TTL-based auto-expiry at query time
- Dedup skips expired entries so replacements are not silently merged
- Stats now reports ExpiredCount and ActiveCount
- EventExpired lifecycle event for cache boundary managers
- REST endpoints: POST /v1/memory/expire, POST /v1/memory/supersede
- MCP tools: memory_expire, memory_supersede
- 12 new tests covering all expiry and supersession paths

Closes #79

Co-authored-by: Ona <no-reply@ona.com>
@Siddhant-K-code Siddhant-K-code added the enhancement New feature or request label May 9, 2026
@Siddhant-K-code Siddhant-K-code merged commit 8260f4f into main May 9, 2026
1 of 2 checks passed
@Siddhant-K-code Siddhant-K-code deleted the feat/memory-expiry-supersession branch May 9, 2026 07:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support explicit memory expiry and supersession

1 participant