feat(memory): temporal validity and supersession reasons#6
Merged
Conversation
Split supersession into two semantically distinct reasons so agents can
distinguish "the world changed" from "the old record was never true":
deprecate_context now accepts supersession_reason ("changed" default sets
valid_until on the old record; "corrected" retracts it on the belief axis
without closing its valid-time window) and an optional initiator for audit.
search_context gains an optional valid_at post-filter (service-layer only,
no new Firestore indexes needed) so callers can query facts as of a point
in time. All fields are optional and backward compatible.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements INVEST #2 from
metacortexplan.md(Temporal Validity / Fact Versioning), including the design-review split of supersession into two semantically distinct reasons:changed(default) — the old fact was true of its era (e.g. a job switch). Setsvalid_untilon the deprecated document; it remains true-of-period for valid-time slices covering that window.corrected— the old record was never true (e.g. a mistyped date). Retracts it on the belief axis (supersession_reason: "corrected") without closing a valid-time window, excluding it from valid-time results while keeping it in the audit trail.Changes:
MemoryMetadatagains optionalvalid_from,valid_until(epoch ms),supersession_reason("changed" | "corrected"), andinitiator("user" | "agent").deprecate_contextaccepts optionalsupersession_reason(default"changed") andinitiator; response payload now includesitem.supersession_reason.search_contextaccepts optionalvalid_at(epoch ms); implemented as a service-layer post-filter after the vector search returns (no new Firestore composite indexes required). A document matches iff(valid_from absent or <= valid_at) AND (valid_until absent or > valid_at) AND supersession_reason !== "corrected".remember_context/storeContextaccept optionalvalid_from/valid_untilpassthrough at the type level (not yet exposed as an MCP input onremember_context, per the agreed scope).metacortexplan.mdINVEST Add Claude Code GitHub Workflow #2 status → Implemented 2026-07-11;CLAUDE.mdtool table and data-flow descriptions updated for the newdeprecate_context/search_contextcontracts.Test plan
npm --prefix functions run build— zero errorsnpm --prefix functions test— 56/56 passing, 73.27% overall coverage (≥60% required)service.test.ts: default reason +valid_until,correcteddoes not setvalid_until,initiatorrecorded,valid_atwindow filtering (inside/before/after),correctedexclusion, absent-fields-always-matchmcp.integration.test.ts:deprecate_contextwithsupersession_reason/initiatorover real MCP Streamable HTTP transport,search_contextwithvalid_atfor both"corrected"exclusion and"changed"window behaviorInMemoryMemoryRepositoryfake mirrors the realFirestoreMemoryRepository.deprecate()behavior exactly🤖 Generated with Claude Code