Skip to content

[bug] Persona rows can be archived then restored into a permanently stuck pending_embedding state #1885

Description

@yyhhyyyyyy

Summary

The generic management mutations have no kind guard:

  • forgetMemory / archiveUserMemory (src/main/presenter/memoryPresenter/services/managementService.ts:67-105) archive any row, including kind='persona'.
  • restoreMemory (managementService.ts:52-65) restores any archived row to pending_embedding.

Persona (and working) rows are permanently excluded from the embedding pipeline (agentMemoryTable.listPendingEmbedding / requeueForEmbedding filter kind NOT IN ('persona','working')), so a restored persona row is stuck in pending_embedding forever: getHealth().embeddings.pending and getStatus().pendingEmbedding never drain, and the persona state machine's fts_only invariant is broken.

The path is reachable from the UI: listMemories includes persona rows (managementService.ts:110), and the Memories tab renders them with archive/restore actions. Also note archiving an active persona is a silent no-op for injection (getActivePersona ignores status), which is misleading on its own.

Severity

P2 — state corruption via a legitimate management surface; consequence is permanent health/status pollution and lifecycle-invariant bypass.

Fix direction

Refuse persona/working kinds at the archive/restore/forget boundary, exclude persona rows from the generic memory.list surface (the Persona tab already owns them), and repair already-stuck rows back to fts_only during cheap maintenance.

SDD doc: docs/issues/memory-audit-hardening/ (spec.md + plan.md + tasks.md)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions