v0.2.13
moorcheh-ai/memantov0.2.13Aug 4, 2026by het0814
AI Summary
Fixes multi-type recall bug, hardens session storage, fixes temporal recall correctness, and opens `source` label for per-writer attribution.
Key Highlights
- Multi-type recall now works (OR logic instead of AND)
- Session storage hardening (atomic writes, permissions, per-agent locks)
- Temporal recall fixes (as-of expiry, date-only parsing)
- Open `source` label for per-writer attribution
New Features
- Multi-type recall fix
- Session storage hardening
- Temporal recall fixes
- Open source label
Full Release Notes
# Release Notes for v0.2.13
This release fixes a major **multi-type recall bug** (querying multiple memory types returned nothing because filters were AND'd instead of OR'd), hardens **session storage against corruption and races** (file permissions, atomic writes, Windows lock handling), closes a long batch of **temporal recall correctness bugs** (as-of/expired memories, date-only bounds, version-aware dedup, multi-line title corruption), and makes memory `source` an open per-writer attribution label instead of a fixed enum.
## New Features
- **Open `source` label for per-writer attribution** (`memanto/app/constants.py`,
`memanto/app/core.py`, `memanto/app/models/__init__.py`)
- `source` is no longer restricted to a fixed enum — any writer (CLI, MCP,
LangGraph, Hermes, CrewAI, conversation-extraction, migration) can now
stamp its own identifying label, enabling proper per-writer attribution in
recall output instead of everything collapsing into a few generic values.
## Bug Fixes
- **Multi-type recall returned nothing** (`memanto/app/services/memory_read_service.py`)
- Requesting more than one memory type built a query like
`"#memory_type:fact #memory_type:preference"`, which Moorcheh's keyword
syntax treats as an AND filter that no single document can satisfy — so
multi-type recall silently returned zero results. Fixed to issue one query
per type and union the results (now parallelized for latency).
- **Session storage hardening** (`memanto/app/services/session_service.py`,
`memanto/app/utils/atomic_write.py`)
- Session/secret files (which hold live bearer tokens) are now created with
`0o700`/`0o600` permissions, symlinks are skipped rather than followed, and
writes go through an atomic `O_EXCL` temp-file + `os.replace` pattern
instead of writing in place.
- Session lifecycle locks are now scoped per-agent (was a single global
lock), renewal is serialized against termination, concurrent auto-renewal
races are fixed, and external session-marker races are tolerated instead
of raising.
- Windows-specific: non-blocking lock retry via `msvcrt`, plus handling for
additional `OSError` cases during session loading with improved error
logging.
- Sessions are now preserved across interrupted writes instead of being
left corrupted mid-write.
- **Temporal recall correctness** (`memanto/app/services/memory_read_service.py`,
`memanto/app/utils/temporal_helpers.py`)
- `search_as_of` (point-in-time recall) now correctly recalls memories that
were valid at the queried time but have since expired — it previously
delegated to a helper that always filtered by *current* wall-clock time.
- As-of deduplication is now version-aware: a delete-and-recreate update
that briefly exposes both the old and new document with the same id no
longer causes the wrong version to win against `created_before`.
- Date-only `as_of` cutoffs (e.g. `"2026-06-01"`) are now detected by
parsing instead of string shape, fixing rejection of valid ISO-8601 basic
format dates; date-only end-of-day bounds now correctly keep the final
sub-second of the day instead of dropping it.
- "Yesterday" temporal recall is now bounded to that calendar day instead of
a rolling 24h window.
- `expires_at` values stored as `datetime` (not just ISO strings) are now
handled correctly in the as-of expiry path.
- **Multi-line memory title corruption** (`memanto/app/core.py`,
`memanto/app/services/memory_read_service.py`)
- A title containing a newline broke the `"[TYPE] title\n\ncontent"`
document round-trip — the reader's prefix regex couldn't cross the
embedded newline, corrupting the parsed title/content split. Fixed with a
partition-based parser that handles embedded newlines correctly.
- **`source_ref` dropped from recall responses** (`memanto/app/routes/memory.py`)
- `source_ref` is now preserved end-to-end in recall API responses instead
of being silently dropped.
- **MCP integration repairs** (`integrations/mcp/memanto_mcp/{lifecycle,tools}.py`)
- Fixed `remember`, `list_agents`, `answer`, and `recall` MCP tools that had
regressed; automatic agent creation is now restricted to avoid unexpected
agent proliferation; each agent now gets an isolated session client
initialized independently (was a shared/serial init path).
- **LangGraph store fixes** (`integrations/langgraph/langgraph_memanto/store.py`)
- Repeated `put()` calls to the same key now correctly upsert (including
under concurrent writers) instead of duplicating; removed a local lock-striping
scheme and rate-limit fallback that masked real errors.
- **Config / metadata persistence made crash-safe** (`memanto/cli/config/manager.py`,
`memanto/cli/connect/agent_registry.py`)
- Config writes and local agent-metadata writes are now atomic; a corrupt
local agent metadata file is treated as absent instead of breaking agent
listing, and surfaces as a warning in the list payload; `connect` no
longer duplicates global instruction paths; export caches are now isolated
per backend (cloud vs on-prem) instead of bleeding into each other.
- Memory sync now refreshes the export before syncing to a project (and
reports the refreshed count) instead of syncing a stale cache.
- **Claude Code integration: turn anchoring and negation** (`integrations/claudecode/hooks/`,
`memanto/app/services/memory_parsing_service.py`)
- The `Stop` hook now distills only the current conversation turn instead of
re-processing prior turns; turn anchoring and embedding-query bounds
hardened, including bounding daily-summary embedding queries.
- Negated preferences (e.g. "I don't like Python") are now classified as
preferences instead of misfiled as instructions.
- **Answer generation called directly from the UI** (`memanto/app/clients/moorcheh.py`)
- The Web UI's answer panel now calls the `answer` function directly through
the client rather than an intermediate path that had drifted out of sync.
- **VoltAgent `defaultLimit` validation** (`sdks/typescript/src/integrations/voltagent.ts`)
- `defaultLimit` is now validated at tool-construction time instead of
failing later at call time.
- **on-prem: `moorcheh-client` 0.1.5 layout support** (`memanto/app/clients/backend.py`)
- Adapted to the reorganized package layout shipped in `moorcheh-client`
0.1.5.
## Tests
- New `tests/test_as_of_date_only_parsing.py`, `tests/test_as_of_expired_recall.py`,
`tests/test_memory_read_multi_type.py`, `tests/test_session_summary_concurrency.py`,
`tests/test_postcommit_summary_resilience.py`, `tests/test_title_newline_roundtrip.py`,
`tests/test_moorcheh_user_config_compat.py`, `tests/test_daily_summary_query_length.py`,
`tests/test_review_followups.py`.
- Large expansion of `tests/test_unit.py`, `tests/test_api.py`, and MCP/LangGraph
integration test suites covering every fix above.
## Full Changelog
Full Changelog: https://github.com/moorcheh-ai/memanto/compare/v0.2.12...v0.2.13