v0.2.16

moorcheh-ai/memantov0.2.16Aug 20, 2026by het0814

AI Summary

Replaces TTL-only expiry with a full memory lifecycle policy system including retention tables, named rules, presets, and a purge pipeline.

Key Highlights

  • New Memory Expiry Policies: Active/expired status, retention tables, named match rules
  • Three built-in presets: conservative, balanced, aggressive
  • Purge pipeline (`memanto policy purge`) for deleting expired memories
  • Removal of entire `legacy/` dead code folder

New Features

  • Lifecycle policy system
  • Policy presets
  • Purge pipeline
  • Web UI Policy page

Full Release Notes

# Release Notes for v0.2.16

This release replaces Memanto's old TTL-only expiry with a full **memory lifecycle policy system**: active/expired status, per-type retention tables, named match rules, presets, a sweep+purge pipeline, expire actions wired into conflict resolution, and a dedicated policy page in the Web UI , plus a cluster of session-token, pagination, and TypeScript SDK reliability fixes.

## New Features

- **Memory expiry policies** (`memanto/app/services/memory_policy_service.py`,
  `memanto/app/services/policy_presets.py`, `memanto/cli/commands/policy.py`,
  `memanto/app/routes/memory.py`)
  - Replaces the old flat TTL/`expires_at` model with a durable
    **active/expired** memory status. Nothing expires implicitly — a policy
    only takes effect when a sweep runs (`memanto policy apply` or the
    `POST /{agent_id}/policy/apply` route), which stamps `status`,
    `expired_at`, and `expired_by` onto each matching record, so a recalled
    memory can say *when* it expired and *which rule* did it.
  - A policy has two halves: a per-type **retention** table (e.g.
    `context: 7d`, `preference: never`) for broad strokes, and named
    **rules** — sharper match blocks (by tag, provenance, confidence
    threshold) evaluated in order, first match wins, letting a rule *pin* a
    memory active by expiring `after: never`.
  - Durations parse `"7d"` / `"3mo"` / `"never"` (m/h/d/w/mo/y units, `mo` =
    30 days).
  - Three built-in **presets** — `conservative`, `balanced`, `aggressive` —
    each a complete policy users can enable in one command
    (`memanto policy apply-preset <name>`) and then customize; every preset
    treats `preference`/`instruction`/`relationship` as durable and never
    expires anything tagged `pinned`.
  - **Purge**: a separate, opt-in step (`memanto policy purge`) that actually
    deletes memories that have been expired longer than
    `purge_expired_after`, kept deliberately distinct from expiry so
    "expired" data stays recallable via `recall_as_of` until a user
    explicitly purges it.
  - New CLI command group `memanto policy {show, list-preset, apply-preset,
    apply, purge}`.
  - New REST endpoints: `POST /{agent_id}/memories/{memory_id}/expire`,
    `GET`/`PUT /{agent_id}/policy`, `GET /{agent_id}/policy/presets[/{name}]`,
    `POST /{agent_id}/policy/preset`, `POST /{agent_id}/policy/apply`,
    `POST /{agent_id}/policy/purge`.
  - **Web UI**: new Policy page for viewing/editing retention and rules,
    per-row lifecycle actions (expire a memory directly from the Memory
    Explorer), and a labelled purge-window slider (number + unit selector,
    including a month unit) replacing the old raw duration text input.
  - **Conflict resolution** gains explicit expire actions, so a conflict can
    be resolved by expiring one side instead of only keep/delete/manual.
  - TypeScript SDK exposes the full policy surface (`lifecycle.ts`) alongside
    the existing REST bindings.

## Improvements

- **Dead code fully removed** (`memanto/app/legacy/`)
  - The entire `legacy/` dead-code folder (auth, context,
    context_summarization_service, idempotency, memory, memory_validation_service,
    namespaces, phase_d, safe_deletion, tracing, universal_endpoints and
    friends — ~3,000 lines) was deleted outright now that the TTL rework made
    the last remaining reasons to keep it around moot.

- **Session token handling** (`memanto/app/routes/auth_deps.py`,
  `sdks/typescript/src/index.ts`)
  - Renewed session tokens are now correctly returned via the response header
    on renewal, instead of only updating server-side state.
  - Fixed a session-deletion bug in `delete_agent` where the client's local
    session state wasn't cleared consistently.
  - TypeScript SDK: expired sessions are now retried automatically instead of
    failing the call; concurrent server-startup requests are serialized so
    two near-simultaneous session-bootstrapping calls don't race.

- **Pagination guard against repeated tokens** (`memanto/app/services/memory_read_service.py`)
  - Document pagination now tracks seen `next_token` values and stops instead
    of looping forever if the backend ever returns the same token twice.

- **Provenance preserved on memory update** (`memanto/app/services/memory_write_service.py`)
  - `update_memory` now preserves the original `provenance` value instead of
    resetting it, so an edited memory doesn't lose its "how was this obtained"
    history.

- **Daily-summary confidence pairing fixed** (`memanto/app/services/summary_visualization_service.py`)
  - Confidence values in the generated summary are now matched to the correct
    memory block (bounded to that block's heading range) instead of
    potentially attaching to an adjacent block.

## Tests

- New `tests/test_memory_policy.py` (588 lines) covering the full policy
  engine: parsing, retention tables, rule matching, presets, sweep, and
  purge.
- New `tests/test_pagination_guard.py`; expanded `tests/test_as_of_expired_recall.py`,
  `tests/test_cors_fix.py`, `tests/test_memory_read_filter_sanitization.py`,
  `tests/test_api.py`, `tests/test_cli.py`, `tests/test_unit.py`.
- New `sdks/typescript/test/lifecycle.test.ts`; expanded `memanto.test.ts` for
  session retry and startup serialization.

## Full Changelog

Full Changelog: https://github.com/moorcheh-ai/memanto/compare/v0.2.15...v0.2.16