v0.2.11
Release Notes for v0.2.11
This release adds real write-time contradiction detection and resolution (replacing the "MVP direct store" stub with an actual MemoryValidationService and batch-prefetch performance path), plus a very large batch of validation and correctness fixes across config management, CLI connect/skill install, MCP session isolation, and the LangGraph/Hermes/CrewAI integrations.
New Features
- Write-time memory contradiction resolution (
memanto/app/services/memory_validation_service.py,
memanto/app/services/memory_write_service.py)- Write-time validation was previously stubbed out ("MVP direct store"), so
logically contradictory memories were stored blindly. New
MemoryValidationServicedetects contradictions deterministically (no LLM
on the write path): a stored active memory with the same type and title
(case-insensitive) but different content is a contradiction. - Resolution follows the
keep_newconvention already used by the offline
conflict report: the old record is preserved as history
(status=superseded,superseded_by/superseded_at— the same fields
search_as_ofalready reads) via the same delete-and-recreate pattern
update_memoryuses; the new record is stored active. - Contradictions within a single batch resolve last-wins, with earlier
conflicting entries stored as superseded history. - Only memory types in
settings.REQUIRE_VALIDATION_FORare checked, keeping
the write path cheap for types that don't need it. - Batch prefetching: contradiction candidates for an entire batch are
fetched together up front instead of one Moorcheh lookup per memory,
substantially reducing write latency for batch operations. - The supersede step now uploads the replacement document directly (instead
of a separate update call) and no longer deletes the original record if
the upload fails — a failed supersede leaves the original intact rather
than losing data. - Manual conflict resolution now stores the replacement content before
deleting the superseded record, and a failed deletion during resolution
correctly leaves the conflict marked unresolved instead of silently
dropping it.
- Write-time validation was previously stubbed out ("MVP direct store"), so
Improvements
-
Config validation hardening (
memanto/cli/config/manager.py,
memanto/app/ui/routes/ui_router.py,memanto/cli/schedule_time.py)- Server URLs are normalized and ports validated before being written to
config; session/answer config edits are validated against their schema;
config setters now guard against malformed config sections instead of
crashing; schedule times are validated (format + range) before a
scheduled job is enabled, both via the CLI and the UI (invalid times now
return 400 instead of silently accepting garbage).
- Server URLs are normalized and ports validated before being written to
-
Moorcheh client cache invalidation (
memanto/app/clients/moorcheh.py)MoorchehClientSingletonnow tracks the config it was built from
(backend, URL, timeout / API key) and rebuilds the cached client when
that config changes, instead of serving a stale client after a backend
or API-key switch.
-
Avoid storage writes during service initialization (
memanto/app/services/session_service.py,
memanto/app/services/agent_service.py)SessionService/AgentServiceno longer eagerly create directories or
generate a secret key at construction time; both are now lazy
(created/generated on first actual use), avoiding unnecessary filesystem
writes (and directory creation) just from instantiating the service.
-
memanto connect/ skill install correctness (memanto/cli/connect/engine.py,
memanto/cli/connect/agent_registry.py)- Fixed false-positive shared-skill detection that could report a skill as
installed for one agent when it was actually another agent's install. connect --disconnectnow preserves unmanaged rule files (including
non-UTF-8 ones) instead of deleting content Memanto didn't add.- Hook-cleanup matching (used when disconnecting) tightened to avoid
removing unrelated hook entries.
- Fixed false-positive shared-skill detection that could report a skill as
-
Agent list namespace counts hardened (
memanto/cli/config/manager.py)list agentsnow guards against malformed/missingitem_countor
namespace_namefields in the Moorcheh namespaces response instead of
raising.
-
MCP integration: per-agent session isolation (
integrations/mcp/memanto_mcp/lifecycle.py,
integrations/mcp/memanto_mcp/tools.py)- Concurrent MCP tool calls for different agent IDs no longer share one
SdkClientsession — each agent gets its own isolated, cached client, with
batch payload validation happening before any readiness side effects and
newly created scoped clients only cached once activation actually succeeds. - MCP
batch_remembernow guards against and normalizes malformed item
results instead of propagating a bad shape.
- Concurrent MCP tool calls for different agent IDs no longer share one
-
LangGraph integration fixes (
integrations/langgraph/langgraph_memanto/{store,tools}.py)- Non-string content values are stringified before being written to the
store (previously could raise).min_confidencesearch filtering fixed.
Setup now retries after an activation failure instead of getting stuck.
Input limits enforced onremember.
- Non-string content values are stringified before being written to the
-
Hermes / CrewAI integration fixes (
integrations/hermes-agents/,integrations/crewai/)- Fixed agent-id truncation collisions in Hermes (two different agent IDs
could truncate to the same internal id). Hermes memory-mirror writes on
exit are now non-blocking. CrewAIremembernow enforces the same input
length limits as the core API.
- Fixed agent-id truncation collisions in Hermes (two different agent IDs
-
Memory validation / parsing hardening (
memanto/app/services/memory_parsing_service.py,
memanto/app/models/__init__.py)- Fixed the ambiguity guard being systemically bypassed by common auxiliary
verbs (is/are/was/were) matchingSTRONG_FACT_PATTERNS. - Memory type is now schema-validated on write instead of accepted as any
string;SourceTypevalidation is strict and rate-limiting now fails
closed on error instead of open. - Tags and source labels are now length-bounded before storage (applies to
bothrememberand memory edits) using shared Pydantic
Annotated[StringConstraints]validators. - Fail-fast on malformed storage responses in the core write path,
memanto migrate, and MCPbatch_remember.
- Fixed the ambiguity guard being systemically bypassed by common auxiliary
-
Timestamp formatting fix (
memanto/app/services/memory_read_service.py)- Epoch-integer timestamps are now coerced to ISO strings during memory-read
formatting instead of being returned as raw ints, which broke downstream
date parsing.
- Epoch-integer timestamps are now coerced to ISO strings during memory-read
-
Unicode agent-ID isolation — agent ID validation is now centralized and
Unicode-normalized, fixing a case where visually-similar Unicode agent IDs
could collide or bypass isolation.
Tests
- New
tests/test_contradiction.py,tests/test_conflict_manual_resolution.py,
tests/test_conflict_resolution_delete_failures.py,tests/test_connect_engine.py,
tests/test_connect_detection.py,tests/test_config_manager_setters.py,
tests/test_schedule_time_validation.py,integrations/mcp/tests/test_lifecycle.py. - Large expansion of
tests/test_api.py,tests/test_backend.py,
tests/test_unit.py, and per-integration test suites covering every fix
above.
Full Changelog
Full Changelog: v0.2.10...v0.2.11