Skip to content

recall: respect invalidation and current-state semantics #169

Description

@jack-arturo

Problem

The Memora/FAMA diagnostic work in verygoodplugins/automem-evals exposed a recall-time current-state gap: AutoMem can retrieve relevant evidence while answer-level evaluation still fails because stale, removed, expired, or superseded memories remain active in /recall output.

This is not just a benchmark adapter concern. The graph already supports relation labels such as INVALIDATED_BY and EVOLVED_INTO, and memories already support temporal validity fields (t_valid, t_invalid), but /recall currently treats those as context rather than state semantics.

Evidence

Local diagnostic scope, not a public benchmark claim:

  • A controlled FAMA-style smoke test seeded old/current/retracted facts and added INVALIDATED_BY, EVOLVED_INTO, and CONTRADICTS edges.
  • /recall returned current facts but still leaked stale/retracted facts.
  • A small Memora/FAMA answer-level slice showed that retrieval leakage diagnostics can undercount answer-level stale-fact failures.
  • The local automem-evals workaround had to build a resolved-state ledger outside AutoMem to suppress superseded raw events before answer generation.

Related local artifact: automem-evals/data/results/memora-fama/20260522T140142Z-automem-relations-weekly-software_engineer/memora-fama-report.md.

Proposed behavior

Add recall-time current-state semantics so /recall defaults to active memories only:

  • Suppress memories with archived=true.
  • Suppress memories whose t_valid is in the future.
  • Suppress memories whose t_invalid is in the past.
  • Suppress memories with an outgoing INVALIDATED_BY or EVOLVED_INTO edge to an active replacement.
  • Do not suppress on CONTRADICTS alone.
  • If a suppressed memory has an active replacement, allow the replacement to be injected as a state_replacement result when it passes caller filters.
  • Add aggregate diagnostics such as state_filter.suppressed_count and state_filter.replacement_count; include IDs/reasons only under an explicit debug flag.

Acceptance criteria

  • /recall supports current_only defaulting to true and state_debug defaulting to false.
  • current_only=false preserves legacy behavior for diagnostics/backcompat.
  • Vector, keyword, tag-only, and relation-expanded recall paths apply the same current-state filter.
  • CONTRADICTS does not suppress by itself.
  • PATCH /memory/<id> preserves and syncs t_valid / t_invalid to Qdrant payloads.
  • Tests cover expired, future-valid, invalidated, evolved, contradictory, and replacement-injection behavior.

Related work

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    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