Skip to main content
spaceduck uses a layered memory system. Short-term memory lives inside each conversation. Long-term memory persists across conversations and is automatically extracted, classified, and deduplicated.

Layers

Extraction pipeline

After every message, spaceduck runs a two-stage extraction pipeline asynchronously (never blocks the response):
  1. Regex extraction — pattern-matches identity facts (“My name is…”, “I live in…”) for immediate capture
  2. LLM classification — the chat model extracts and classifies memories with structured output
Each candidate is assigned:
  • Kind: fact, episode, or procedure
  • Importance: trivial / standard / significant / core / critical
  • Confidence: speculative / likely / stated / certain
  • Tags: 1-4 lowercase topic labels
  • Retention decision: store or reject (with reason)
A deterministic “steel gate” validates the LLM output before anything touches the database.

Semantic dedup and contradiction detection

When a new memory is stored, it is embedded and compared against existing memories using cosine similarity: If the LLM arbiter says “contradiction”, the old memory is marked superseded and the new one becomes active. If “consistent”, both coexist. This handles corrections like “I live in Paris” followed by “I live in Tokyo” — the location change is detected and the old fact is retired.

Recall

When building context for a response, spaceduck retrieves memories using hybrid scoring:
  1. Vector search — cosine similarity between query embedding and stored memory embeddings
  2. Keyword search — FTS5 BM25 full-text search
  3. Reciprocal Rank Fusion (RRF) — merges both result lists into a single ranking
  4. Post-fusion multipliers — importance, confidence, recency decay, and scope boost
Memories are scoped: thread > project > global. Thread-scoped memories decay faster (30-day half-life vs 90-day for global).

Procedure subtypes

Procedures are further classified to control injection priority:

Memory status lifecycle

Memory isolation

When the scheduler runs tasks autonomously, their memory writes carry provenance so they don’t pollute interactive recall. Each memory record stores a taskId (which task wrote it) and optionally a skillId (which skill was active). This enables:
  • Scoped recall — scheduled tasks see their own memories plus global ones, not noise from other tasks. Controlled via excludeTaskMemories and sourceTaskId filters.
  • Write budgets — each task is limited to maxMemoryWrites (default 10). A counting proxy wraps the store and silently drops writes once the limit is reached.
  • Cascading purge — when a skill is uninstalled, all memories tagged with its skillId are deleted automatically.
  • Injection detection — all content passes through detectInjection before storage. Task-sourced content uses strict mode (single pattern match rejects); user input uses relaxed mode (2+ matches required).
See Security for the full defense-in-depth model.

Memory viewer

The memory viewer lets you inspect, search, and manage everything Spaceduck remembers. Access it from the Brain icon in the sidebar.
  • Browse all stored memories (facts, episodes, procedures) with filters for kind, status, and scope
  • Search using the same hybrid retrieval pipeline (vector + FTS + RRF) the agent uses internally
  • Delete individual memories that are wrong, outdated, or no longer useful
  • Provenance each card shows where the memory came from: which skill wrote it, which task created it, and the source type (user message, assistant, tool result, etc.)

Memory API

The viewer is backed by authenticated HTTP endpoints on the gateway:

Configuration

Memory settings live in Settings > Memory: