Skip to content

Fade time-sensitive memories, and rename the repo to match the product - #5

Merged
Ninadnj merged 1 commit into
mainfrom
feat/memory-decay
Aug 16, 2026
Merged

Fade time-sensitive memories, and rename the repo to match the product#5
Ninadnj merged 1 commit into
mainfrom
feat/memory-decay

Conversation

@Ninadnj

@Ninadnj Ninadnj commented Aug 15, 2026

Copy link
Copy Markdown
Owner

Two things: the last item on the roadmap, and the repo name.

Memory decay

A month-old "currently implementing multilingual support" was recalled with exactly the same confidence as a fresh fact. That's worse than forgetting — it actively misleads the next session.

Similarity is now multiplied by 0.5 ** (age / half-life):

Type Half-life Why
state 7 days "Currently working on…" goes stale fastest
handoff 7 days Next steps are done or abandoned by then
worklog 21 days What happened still orients you, but fades
decision project issue fact never True until explicitly superseded

Not everything should fade, and that's the design decision worth calling out. "Bookings are stored in UTC" is as true in a year as on the day it was written — fading it would quietly lose the memories most worth keeping. What goes stale is the record of a moment. Correct a decision with memory_update; let a status note fade on its own.

Combined with the relevance floor, stale notes leave recall with no cleanup required. Measured: at 45 days a state memory is down to 1% of its score while a decision of the same age is untouched.

mem_0002  [state · 45d, faded to 1%] Currently implementing multilingual chatbot support.
mem_0001  [decision · 45d] Bookings are stored in UTC; the UI converts.

Four details that took thought:

  • Only positive similarities are scaled. Scaling a negative score moves it toward zero — which would promote an unrelated old memory rather than bury it. Tested.
  • An unreadable timestamp decays not at all, rather than sinking a memory nobody can date.
  • Future timestamps are clamped, so clock skew can't boost a memory above a genuinely fresh one.
  • agent-memory list shows age and fade. It's the command you run to decide what to correct, so it should show what's going stale.

recall --no-decay ranks on similarity alone. The published evaluation is unchanged — its memories are written fresh, so every factor is 1.0.

Rename

The repo was still ai-agent-memory-scaffold while shipping agent-memory-engine: searching for the project by name found nothing, and the first impression was a mismatch. Renamed on GitHub (the old URL 301-redirects), with every reference updated — badges, clone instructions, pyproject URLs, the scaffold's own README.

The repository description also still carried the "78% fewer context tokens at 93% recall" framing that the README corrected weeks ago. It now describes what's actually claimed.

Tests: 123 → 141.

🤖 Generated with Claude Code

Decay
-----
A month-old "currently implementing X" was recalled with exactly the same
confidence as a fresh fact. That is worse than forgetting: it actively
misleads the next session.

Similarity is now multiplied by 0.5 ** (age / half-life), so a memory at
its half-life must be twice the match to rank where it did when fresh:

    state     7 days   "currently working on…" goes stale fastest
    handoff   7 days   next steps are done or abandoned by then
    worklog  21 days   what happened still orients you, but fades
    decision, project, issue, fact — never

Not everything should fade. "Bookings are stored in UTC" is as true in a
year as on the day it was written; fading it would quietly lose the
memories most worth keeping. What goes stale is the record of a moment.
Correct a decision with memory_update; let a status note fade on its own.

Combined with the relevance floor, a stale status note eventually leaves
recall without any cleanup: at 45 days a `state` memory is down to 1% of
its score while a `decision` of the same age is untouched.

Details that matter:
- Only positive similarities are scaled. Scaling a negative one moves it
  toward zero, which would promote an unrelated old memory rather than
  bury it.
- An unreadable timestamp decays not at all, rather than sinking a
  memory no one can date.
- Future timestamps are clamped, so clock skew cannot boost a memory.
- `agent-memory list` now shows each memory's age and how far it has
  faded — that is the command you run to decide what to correct, so it
  should show what is going stale. `recall --no-decay` disables it.

The published evaluation is unchanged: its memories are written fresh, so
every factor is 1.0.

Rename
------
The repository was still called ai-agent-memory-scaffold while shipping
agent-memory-engine, so searching for the project by name found nothing
and the first impression was a mismatch. Renamed on GitHub — the old URL
301-redirects — and every reference updated: badges, clone instructions,
pyproject URLs, the scaffold's own README. The repository description
also still carried the "78% fewer tokens" framing the README corrected
weeks ago; it now describes what is actually claimed.

Tests 123 -> 141.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ea2f50a1da

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agent_memory/store.py
Comment on lines +62 to +63
"handoff": 7.0, # next steps are usually done or abandoned by then
"worklog": 21.0, # what happened still orients, but fades

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Apply decay to automatically injected session notes

The new half-lives do not affect the primary startup paths: MemoryStore.boot() unconditionally returns the latest handoff, while hooks.session_start() directly injects the latest handoff and worklog. Consequently, after a project is idle for weeks, these entries are still presented at full prominence on every boot despite their configured 7/21-day half-lives; decay currently applies only when entries pass through cosine recall.

Useful? React with 👍 / 👎.

Comment thread src/agent_memory/store.py
Comment on lines +431 to +433
factors = np.array(
[decay_factor(e) for e in self._entries], dtype=np.float32
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Refresh time-sensitive memories when revising them

When memory_update revises an old state or changes an old entry to a decaying type, _revise() preserves the original created_at; this factor therefore treats the newly corrected content as already stale and may immediately rank it near zero or filter it below min_score. The timestamp used for decay needs to reflect the revision time, such as by refreshing it for changed time-sensitive entries or tracking an updated_at value.

Useful? React with 👍 / 👎.

@Ninadnj
Ninadnj merged commit 6b25f51 into main Aug 16, 2026
4 checks passed
@Ninadnj
Ninadnj deleted the feat/memory-decay branch August 16, 2026 19:50
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.

1 participant