Skip to content

X10.1 — add-long-term-memory-governance #79

Description

@HsienW

Labels: second-stage, layer-2, backend
Milestone: Second Stage - Layer 2: Platform Governance
Dependencies: X7, X8.7, X8.9, X9, X10


Establish Scope-Aware, Versioned, Bi-Temporal Long-Term Memory Governance on Top of LangGraph Store

Goal

Complete the remaining Memory half of the original "Memory + Context Budget" gap by adding governed cross-thread memory using LangGraph Store (or the native Store boundary validated by X0), while preserving X7 Context Budget priorities.

The objective is not "remember everything." Persist only durable, useful, provenance-aware Memory that respects visible/write scopes, concurrent updates, correction/restore, temporal validity, explicit conflict handling, and never overrides current explicit intent.

Background

X7 already provides quantitative Context Budgeting, priority assembly, and compression. X9/X10 provide a concrete Recommendation workload, so Memory can now be designed against real intent/constraint semantics.

Scope

Part A: Memory Record Contract

interface LongTermMemoryRecord<TValue = unknown> {
  memoryId: string;
  namespace: {
    tenantId: string;
    principalId: string;
    domain?: string;
    scopeId: string;
  };
  memoryType:
    | "preference"
    | "negative_preference"
    | "accepted_choice"
    | "task_summary"
    | "service_context";
  value: TValue;
  provenance: {
    source: "user_explicit" | "user_feedback" | "task_result" | "model_inferred";
    sourceRef?: string;
  };
  confidence: number;
  revision: string;

  // Bi-temporal semantics: when the Memory is considered true vs. when the Runtime recorded it.
  validFrom?: string;
  validUntil?: string;
  recordedAt: string;

  createdAt: string;
  updatedAt: string;
  expiresAt?: string;
}

Part B: Visible Scope vs Writable Scope

Visibility and write authority are separate policies.

type MemoryReadMode = "off" | "writable_scopes" | "visible_scopes";
type MemoryWriteMode = "off" | "writable_scopes";

interface MemoryAccessPolicy {
  readMode: MemoryReadMode;
  writeMode: MemoryWriteMode;
  visibleScopeIds: string[];
  writableScopeIds: string[];
}

Examples:

  • personal preference: visible + writable by principal scope
  • team guidance: visible to members, writable only by designated team/admin scope
  • tenant policy Memory: visible to authorized principals, not writable by normal Agent interaction

X8.7 authorization is the source of truth for visibility/write permission.

Part C: Memory Priority, Bi-Temporal Validity, and Conflict Policy

User explicit current-turn text
  > User current selection
  > High-confidence Vision
  > Long-term Memory
  > Low-confidence model inference

Distinguish:

  • Valid time — when the remembered fact/preference is considered true in the user's/domain timeline
  • Recorded time — when the Runtime learned or persisted that Memory

This allows a newer observation to supersede an older preference without erasing the fact that the older preference was previously valid.

type MemoryRelation =
  | "same"
  | "supersedes"
  | "conflicts"
  | "coexists";

Rules:

  • current-turn explicit intent always wins
  • negative preference cannot silently become positive
  • low-confidence inferred Memory cannot become a Hard Constraint
  • new Memory is classified as same, supersedes, conflicts, or coexists before replacement/merge
  • conflict resolution uses source priority + valid time + recorded time + recency + confidence and is traceable
  • conflict/supersession decisions SHOULD emit X8.9 Decision Provenance instead of silently overwriting older Memory

Part D: Memory Write Policy

Only persist approved sources:

  • explicit user preference/correction
  • accepted recommendation / confirmed outcome
  • stable task summary after completion

Do NOT persist every turn, raw prompts, unrestricted Tool output, transient guesses, credentials, or unmasked PII.

Part E: Optimistic Concurrency and Revision Control

interface MemoryWriteRequest<TValue> {
  memoryId?: string;
  expectedRevision?: string;
  value: TValue;
}

Behavior:

  • matching expectedRevision → update + new revision
  • mismatched revision → conflict; never silently overwrite newer Memory
  • caller must re-read and re-evaluate source/recency/confidence before retrying

Part F: History, Temporal Query, and Restore

Maintain bounded revision history and support restoring an old revision as a new revision. Historical revisions are immutable and retain provenance/audit linkage.

Support bounded point-in-time inspection using valid/recorded timestamps so tests and debugging can answer which Memory would have been considered active at a specific time without introducing a general-purpose temporal database.

Part G: Memory Retrieval + Context Integration

Integrate with X7:

  • retrieve only X8.7-authorized visible Memory
  • reuse X8.9 ContextRef where direct authorized relationships are available; do not turn Memory retrieval into unrestricted graph traversal
  • score relevance before injection
  • inject at P3/P4, never P0/P1
  • respect token allocation
  • attach scope/provenance/confidence/revision metadata to debug/trace context

Part H: Retention, Deletion, and Namespace Isolation

Support TTL/expiry, explicit delete, tenant/principal/domain/scope isolation, correction without losing auditability, and invalidation of future Context injection after delete/expiry.

Excludes

  • ❌ No standalone vector database unless native Store proves insufficient
  • ❌ No unrestricted whole-conversation Memory
  • ❌ No autonomous profile building beyond task-relevant structured Memory
  • ❌ No bypass of X8.7 authorization/tenant isolation
  • ❌ No write access merely because Memory is visible/readable

Acceptance

  • Memory written in Thread A is retrievable in Thread B for same authorized principal/tenant
  • Visible-but-not-writable Memory can be read but not modified
  • Current explicit user preference overrides conflicting historical Memory
  • Memory can represent valid time separately from recorded time without mutating historical revisions
  • New Memory is explicitly classified as same/supersedes/conflicts/coexists before replacement or merge
  • A conflict/supersession decision is traceable through X8.9 Decision Provenance
  • Low-confidence inferred Memory cannot become a Hard Constraint
  • Two concurrent writers with same revision → only one succeeds; other receives revision conflict
  • Older Thread cannot overwrite newer explicit preference without re-read/reconcile
  • Memory history is inspectable and old value can be restored as a new revision
  • Cross-tenant Memory lookup denied
  • Expired/deleted Memory not injected into Context
  • Memory injection respects X7 token budget and exposes scope/provenance/revision metadata in debug/trace
  • Raw prompts, unrestricted conversations, credentials, and unmasked PII are not persisted as Memory
  • npm run lint && npm run test && npm run build all pass

Dependencies

  • Requires X7 Context Budget Governance
  • Requires X8.7 scope/resource authorization
  • Requires X8.9 Decision Provenance / Context References for traceable conflict and supersession decisions
  • Uses X9/X10 Recommendation semantics as the first concrete Memory workload

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

type:feature新功能的請求。type:improvement對現有功能的優化或改進。

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions