v0.2.15

moorcheh-ai/memantov0.2.15Aug 18, 2026by het0814

AI Summary

Fixes a wrong-memory-deletion bug in conflict resolution, OKF tag corruption, UTC/local-date mismatches, and FastAPI header metadata leaks.

Key Highlights

  • Fixed conflict resolution index desync (deleted wrong memory)
  • Fixed OKF export corruption for multi-tag memories
  • Fixed daily analysis UTC/local date alignment
  • Fixed FastAPI header metadata leaking into backend API keys

New Features

  • Conflict resolution fix
  • OKF tag corruption fix
  • UTC alignment fix
  • Conversation extraction char budget fix

Full Release Notes

# Release Notes for v0.2.15

This release closes a large batch of correctness bugs discovered through the bounty program — a wrong-memory-deletion bug in conflict resolution, an OKF tag-export corruption bug, a UTC/local-date mismatch across daily analysis surfaces, a FastAPI header-metadata leak into backend API keys, and several LangGraph/OKF/conversation-extraction edge cases.

## Bug Fixes

- **`resolve_conflict` deleted the wrong memory after the first resolution**
  (`memanto/cli/client/{direct_client,sdk_client}.py`, `memanto/app/ui/static/index.html`)
  - `list_conflicts` returns only *unresolved* conflicts, while
    `resolve_conflict` indexed into the *full* report — the two index spaces
    agreed only until the first resolution, then desynced. A caller (REST API
    or Web UI) resolving by filtered-list position could delete a memory it
    never selected, while the conflict the user actually chose stayed
    unresolved. `list_conflicts` now tags each conflict with its stable index
    into the full report; the Web UI resolves (and keys its DOM elements) by
    that stable index instead of on-screen position; `resolve_conflict`
    rejects an already-resolved index as defense in depth.

- **OKF export corrupted multi-tag memories** (`memanto/app/services/okf_export_service.py`)
  - Moorcheh stores `tags` as a comma-separated string (e.g. `"project, db,
    prod"`), but the OKF renderer wrapped it in `list(tags)`, splitting the
    string character-by-character and emitting garbage one-character tags in
    the frontmatter — every multi-tag memory lost its real tags on export.
    Now splits-and-strips a string `tags` value and passes a list through
    unchanged.
  - OKF markdown-link parsing is now linear-time (was worse-case quadratic).
  - Colliding OKF context filenames are now preserved instead of silently
    overwritten (canonical vs. portable/reserved filename collisions).

- **Daily analysis dates misaligned with UTC storage** (`memanto/app/services/daily_analysis_service.py`,
  `memanto/app/ui/static/index.html`, `memanto/cli/commands/{memory,schedule}.py`)
  - API, CLI, and Web UI daily-analysis date defaults are now aligned to the
    same UTC boundary memories are actually stored under, fixing off-by-one-day
    results near midnight depending on local timezone.

- **FastAPI header metadata leaking into backend API keys** (`memanto/app/clients/moorcheh.py`)
  - An unresolved FastAPI `Header(...)` default object (truthy, not a string)
    could be forwarded to the Moorcheh SDK as if it were a real API key when
    the dependency function was called directly rather than injected —
    fixed to only accept a genuine string as a supplied key.

- **Empty query when a conversation message exceeded the extraction char budget**
  (`memanto/app/services/conversation_memory_extraction_service.py`)
  - If a single message exceeded `MAX_CONTENT_CHARS` (12,000), the extraction
    service dropped it entirely and sent an empty query to `answer.generate`,
    producing an API error or garbage results. The first message is now
    always included (truncated if necessary), newline separators are counted
    in the budget, and the budget was raised to 120,000 chars — the old cap
    was inherited from an embedding-search bottleneck that no longer applies
    now that extraction runs in raw-LLM mode (empty namespace, bypassing
    semantic search).

- **LangGraph key collisions and stale agent locks** (`integrations/langgraph/langgraph_memanto/store.py`)
  - Fixed a key-collision case in `MemantoStore` and stale per-agent locks left
    behind after certain operations; legacy LangGraph key tags are preserved
    for backward compatibility.

- **CLI: minimum-confidence recall filter restored** (`memanto/cli/commands/memory.py`)
  - `memanto recall --min-confidence` had regressed to a no-op; filtering is
    restored and positional recall arguments are preserved.

- **Mem0 export updated to v3 API** (`memanto/cli/analyze/mem0_export.py`)
  - Mem0's export/migrate path now targets their v3 API; pagination-envelope
    handling validates the `next` field before treating pagination as
    finished, instead of terminating early on a malformed page.

- **Incomplete memory exports rejected, with stale-cache fallback preserved**
  (`memanto/cli/client/{direct_client,sdk_client}.py`)
  - An incomplete export refresh is now rejected rather than silently
    accepted as complete, while still falling back to the last good
    (stale-cache) export when a refresh genuinely fails — keeping the
    outage-safety behavior shipped earlier while fixing the incomplete-data
    case.

- **Stale per-agent lock removed on delete** (`memanto/app/services/agent_service.py`)
  - Deleting an agent now cleans up its per-agent lock instead of leaving a
    stale lock object behind.

## Tests

- New `tests/test_conflict_index_desync.py`, and expanded `tests/test_okf.py`,
  `tests/test_backend.py`, `tests/test_cli.py`,
  `tests/test_conversation_memory_extraction.py`, `tests/test_export_resilience.py`
  covering every fix above.

## Full Changelog

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