v3/docs/adr/ADR-368-dream-cycle-memory-selective-persistence.md
Ruflo's AgentDB currently persists full session history (all conversation turns, reasoning traces, intermediate outputs) into memory namespaces. A 2026 peer-reviewed paper (Pedada et al., arxiv:2607.09493, "Shared Selective Persistent Memory for Agentic LLM Systems") demonstrates that naive full-history persistence degrades task completion (71% vs 96% for selective, vs 79% for no memory). The key insight: reasoning traces from past sessions are stale and introduce noise; what reuses cleanly across sessions is only four categories of information.
Additionally, a second 2026 paper (arxiv:2607.14651, "MemPoison") demonstrates that write-time memory defenses fail against compositional attacks, and a third (arxiv:2607.08395, "Token-Flow Firewall") proposes semantic runtime interception before persistence. Ruflo's @claude-flow/security InputValidator currently operates at system input boundaries, not on memory write paths.
Implement a Selective Persistent Memory filter in @claude-flow/memory that:
Categorizes memory writes into one of five buckets at write-time:
TASK_SPEC — task descriptions, goals, acceptance criteriaDATA_SCHEMA — data models, field definitions, API contractsTOOL_CONFIG — tool invocations, endpoint URLs, auth patterns (sans secrets)OUTPUT_CONSTRAINT — output format rules, size limits, required fieldsREASONING_TRACE — all other (ephemeral: summaries, CoT steps, intermediate decisions)Persists only TASK_SPEC, DATA_SCHEMA, TOOL_CONFIG, OUTPUT_CONSTRAINT by default. REASONING_TRACE entries expire after the session TTL (configurable, default 24h).
Adds RBAC to AgentDB namespaces: MemoryNamespace gains an acl: { [role: string]: 'read' | 'write' | 'none' } field so namespaces can be shared cross-user with role-gated access.
Adds a write-time semantic gate in the memory update path that checks writes against a threat pattern list before persistence (Token-Flow Firewall pattern). Implemented as a middleware in AgentDB.store().
Positive:
Negative:
Mitigations:
--memory-selective-filter=off escape hatch for users who need full-history replay// v3/@claude-flow/memory/src/selective-filter.ts
export type MemoryCategory =
| 'TASK_SPEC'
| 'DATA_SCHEMA'
| 'TOOL_CONFIG'
| 'OUTPUT_CONSTRAINT'
| 'REASONING_TRACE';
export interface SelectiveFilterConfig {
persistCategories: MemoryCategory[];
traceTTLMs: number; // default: 86_400_000 (24h)
semanticGate: boolean;
}
export const DEFAULT_FILTER: SelectiveFilterConfig = {
persistCategories: ['TASK_SPEC', 'DATA_SCHEMA', 'TOOL_CONFIG', 'OUTPUT_CONSTRAINT'],
traceTTLMs: 86_400_000,
semanticGate: false, // off by default for private namespaces
};
export function classifyEntry(content: string, metadata: Record<string, unknown>): MemoryCategory {
// Tier-1: structural heuristics
if (metadata.type === 'tool_call' || metadata.type === 'tool_config') return 'TOOL_CONFIG';
if (metadata.type === 'schema' || content.includes('"$schema"')) return 'DATA_SCHEMA';
if (metadata.type === 'task' || metadata.role === 'user' && metadata.isGoal) return 'TASK_SPEC';
if (metadata.type === 'output_spec') return 'OUTPUT_CONSTRAINT';
return 'REASONING_TRACE';
}