Skip to content

memory: add forget/demote (+ observation decay) so stale memories can be superseded #20

Description

@marcmantei

Problem

The agent's long-term memory has no way to forget or demote a stale memory. There is only memory_save; the memory HTTP API (/api/agents/memories*) is read-only (list/search/graph). So once a wrong or obsolete belief is saved at high importance, it persists — and repetitive "observation" memories keep themselves warm via constant access, dominating recall and drowning out newer corrections.

Evidence (operator memory-refresh, 2026-06-19)

The supervisor (main) had accumulated ~50 "worker-healer alert storm / false-positive since May 31" observation memories, all importance: 1.0, with access_count 79–86 and last_accessed/updated_at = today. These made it (a) decline heavy tasks on an obsolete "worker-timeout death-spiral" premise and (b) reflexively skip/confabulate on healer alerts (it invented "8 contradictory alerts" / "docker binary missing", both false).

We loaded 4 authoritative CORRECTION … SUPERSEDES … memories via /api/portal/send. They persisted and are retrievable — but they're outranked in generic recall by the ~50 storm memories, which stay warm through repeated access. Recency doesn't help; the stale cluster never decays. There is no tool or API to demote it, and editing agent.db's forgotten flag directly wouldn't affect the Lance-backed search without an index rebuild (and risks desync).

Proposed

  1. memory_forget agent tool (and/or memory_supersede): let the agent mark a memory forgotten / lower its importance / supersede it by id. Must update the search index (Lance FTS/vector) so forgotten memories drop out of memory_recall and /agents/memories/search, not just the SQLite row.
  2. Decay / TTL for low-value repetitive observations: importance decay over time and/or de-duplication of near-identical recurring observations (the alert-storm cluster is ~50 variations of one observation). A 10-day repeated "false positive" note should not sit at importance 1.0 forever.
  3. Operator memory-mutation API (optional): authenticated PATCH/DELETE on /agents/memories/{id} (set forgotten, adjust importance) so corrections like feat: add dedicated voice model routing and attachment transcription spacedriveapp/spacebot#98 can be applied deterministically instead of hoping memory_save out-ranks the noise.

Acceptance

  • The agent can forget/supersede a memory by id or description, and it no longer surfaces in memory_recall / search (index updated).
  • Repetitive observation memories decay in importance (or de-dupe), so a stale narrative can't dominate recall indefinitely.
  • An authoritative correction (newer memory_save) reliably out-ranks the obsolete cluster it supersedes.

Context

Follow-up to shipyard spacedriveapp#98 (supervisor memory refresh). The corrections are loaded; this issue is what's needed to make such refreshes actually stick. The healer false-positive root causes themselves are already fixed in shipyard (spacedriveapp#115, spacedriveapp#117, spacedriveapp#122).

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions