Skip to main content

Memory Lifecycle

A memory is in exactly one of two states: There is no third state. Expiring is reversible — the memory keeps its content, its timestamps, and an audit trail of why it was retired. Deleting is a separate, permanent operation.
Nothing expires on its own. A memory becomes expired only when an expiry policy sweep runs, a conflict resolution retires it, or you expire it by hand. An agent with no policy set will never expire anything.

The expiry stamp

When a memory moves to expired, three fields are written together:
string
Becomes expired.
string
ISO-8601 timestamp of when it expired.
string
Why it expired — a policy rule name (scratch-notes), a retention-table entry (retention.context), manual, or conflict-resolution.
Restoring clears all three. Because status == "expired" always carries a when and a why, recall can tell you exactly which rule retired a memory and when:

Recall shows both states

By default recall returns active and expired memories together, each labelled. Expired memories are surfaced to the reader, not hidden from them. Narrow with the status filter (--active / --expired on the CLI):
Point-in-time recall is unaffected: --as-of reconstructs what was true at a past date, so a memory that was live then is returned as active even if it has expired since. This is why the expiry stamp is a stored fact rather than something recomputed on every read.

Expiry policies

A policy has two complementary halves, stored per agent at ~/.memanto/policies/<agent-id>.yaml:
retention maps a memory type to a maximum age. rules are named match blocks checked in order — the first one that matches wins and short-circuits the table, so a rule with expire_after: never acts as a pin. A rule’s name is what gets stamped as expired_by.

Match conditions

Every condition you set must match (AND). An empty match block matches everything.

Durations

30m, 12h, 7d, 2w, 3mo, 1y, or never. A month is 30 days — calendar months have no fixed length, and an expiry window does not need one.
Age is measured from updated_at, falling back to created_at. Editing a memory is evidence it is still live, so an edit resets its expiry clock.

Running a sweep

Saving a policy changes nothing on its own. A sweep is what stamps memories:
The nightly memanto schedule enable job runs the sweep for you after the daily summary and conflict detection.

Purging

purge_expired_after is the only destructive automatic step, and it is off by default. It permanently deletes memories that have already been expired for longer than the given window.
Purging is irreversible and unrelated to what the retention table expires. retention decides what becomes expired; purge_expired_after decides when an already-expired memory is destroyed. A policy where apply reports 0 matches can still have memories eligible for purge — the two act on different populations.

Presets

Three bundles ship as starting points, adoptable in one command and editable afterwards: In all three, preference, instruction, and relationship never expire on a timer, and anything tagged pinned is exempt.

Next Steps