Skip to content

Memory protocol mandates unregistered update_memory_md tool — permanent index-drift nag loop; non-atomic MEMORY.md writes #4458

Description

@senamakel

Part of the v0.58.7 → HEAD TinyAgents-migration audit (see parent issue). Repairs the memory read→dedupe→write→update-index protocol (#4444 / PR #4444, commit 19bf3aa).

Problem

The protocol's write cycle can only be closed by a successful update_memory_md call (src/openhuman/agent/harness/memory_protocol.rs:73-76,138-147), and every durable write appends an instruction to call it. But UpdateMemoryMdTool is never registered in the production registry: all_tools_with_runtime (src/openhuman/tools/ops.rs:268-270) registers MemoryStoreTool/MemoryRecallTool/MemoryForgetTool only; the tool is merely re-exported (src/openhuman/tools/impl/filesystem/mod.rs:30) and constructed once in a test. The archivist's named = ["update_memory_md", ...] (src/openhuman/agent_registry/agents/archivist/agent.toml:23) silently resolves away because subagents only filter the parent set.

Result: memory_store succeeds → middleware instructs the model to call update_memory_md → unknown-tool error → tracker never sees IndexUpdate → escalated "MEMORY.md index is drifting… Reconcile it now" on every subsequent write (memory_protocol.rs:138-144) + after_agent stale-index warning every run (src/openhuman/tinyagents/middleware.rs:1589-1603). Permanent, unsatisfiable nag loop; wasted model round-trips; MEMORY.md never index-updated.

Secondary problems (fix together)

  1. update_memory_md writes are an unlocked, non-atomic read-modify-write (src/openhuman/tools/impl/filesystem/update_memory_md.rs:159-190): concurrent runs (parallel forks, cron) lose an append; crash mid-write truncates MEMORY.md. Becomes live the moment registration is fixed.
  2. remember_preference/save_preference durable writes are classified MemoryOp::Other (memory_protocol.rs:79-98) — undocumented gap in write classification.

Fix plan

  1. Register UpdateMemoryMdTool in all_tools_with_runtime (src/openhuman/tools/ops.rs), respecting the same visibility rules as the other memory tools.
  2. Make the write atomic and serialized: temp-file + rename, guarded by a per-workspace async lock (or reuse an existing file-lock helper). The per-run MemoryProtocolTracker has zero cross-run awareness, so file-level safety is the only guard.
  3. Classify remember_preference/save_preference as durable writes in the protocol (or document why not).
  4. Add a startup/registry inventory assertion so a protocol-mandated tool missing from the registry fails a test, not production (mirror the "adapter inventory test" pattern).

Acceptance criteria

  • A live turn that stores a memory can complete the full read→dedupe→write→index cycle with zero unknown-tool errors and no drift warnings.
  • Two concurrent index updates both survive; a killed process never leaves a truncated MEMORY.md.
  • Inventory test fails if memory_protocol.rs mandates a tool that isn't registered.

Metadata

Metadata

Assignees

Labels

agentBuilt-in agents, prompts, orchestration, and agent runtime in src/openhuman/agent/.bugmemoryMemory store, memory tree, recall, summarization, and embeddings in src/openhuman/memory/.priority: highBreaks a specific featuresubtaskSubtask of a larger tracked effort.

Type

No type

Fields

No fields configured for issues without a type.

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions