Memory and Knowledge: Capabilities and Deliberate Omissions
Boundaries among session logs, summaries, skills, session query, and long-term semantic memory
Verdict: DeepSeek Harness Has Durable History and Explicit Recall, but No Default Autonomous Long-Term Memory System
At the pinned baseline, capabilities often collapsed into “memory” actually occupy six distinct layers. The current Session Surface is model working context; JSONL is the complete durable event history; a compaction checkpoint is a lossy same-Session context replacement; a session reference is an explicitly copied cross-Session snapshot; session query/FTS provides reads and lexical retrieval; and Skills are a trusted instruction catalog. Actual external memory databases, knowledge graphs, or other recall backends enter only through default-off Memory MCP examples.
“The log is durable” does not mean “a new Session automatically remembers old Sessions.” Every Provider request is still derived only from the current Session Surface, and the shipped composition contains no first-party pipeline that automatically searches other Sessions, ranks results, and injects them into the prompt. MEMORY-AGENT-CONTEXTSESSION-SURFACE-PROJECTION
1. Put the Six Core Layers and the External Boundary in One Matrix
| Mechanism | Authoritative data | How the model sees it | Cross-Session? | Shipped default |
|---|---|---|---|---|
| Working context | Current Session Surface + current system/tools | deriveMessages() directly forms the request | No | Yes; minimal disables dynamic runtime context |
| Durable history | Append-only Session event log | Only messages remaining on the folded Surface enter requests | Explicitly readable, not automatically recalled | JSONL in Base |
| Compaction | Summary audit event + replacement checkpoint | A checkpoint replaces an older Surface span | No | Present in standard; absent from minimal |
| Session reference | Bounded snapshot of a source Session's current Surface | Injected as sourced user-role context | Yes, as an explicit one-time copy | Opt-in and not mounted by shipped compositions |
| Session query / FTS | Live or persisted logs; disposable derived SQLite index | Read by the Host/UI or optional model tools | Yes, subject to caller authorization | Exact reads on; FTS and model tools off |
| Skills | Instruction definitions from filesystems or runtime providers | Catalog summaries + full bodies on demand | Discovered by workspace/scope; not learned from conversation | Present in standard; absent from minimal |
| Memory MCP | A third-party provider's own storage | The model explicitly calls MCP tools | Provider-defined | All examples off |
“Default” is a composition result, not one boolean. Base mounts JSONL and sessionQuery but configures FTS as openAt: never; the standard preset additionally mounts Skills and compaction; minimal explicitly omits compaction and suppresses dynamic runtime-context snapshots. MEMORY-DEFAULT-COMPOSITIONMEMORY-STANDARD-PRESETMEMORY-MINIMAL-PRESET
2. Working Context Is the Current Surface, Not the Entire Log
claim inbox messages
→ assemble system prompt and tools
→ project dynamic runtime context
→ run agent/pre-step injections
→ append accepted user/context messages durably
→ derive current Surface messages
→ snapshot request header
→ call Provider
The Agent claims input, assembles the prompt, computes runtime context, and lets plugins append context during pre-step. Only accepted messages are then recorded as user/message events. The model call reads session.deriveMessages(), while canonical provider/model, system, and tools are recorded separately in request/header. MEMORY-AGENT-CONTEXT
Only user/message, nonempty assistant/message, and tool/result can become Surface messages. Turn and Step boundaries, raw stream chunks, request headers, and other log-only events never directly enter model history. A replacement-generation change makes the derived cache rebuild from the new Surface. SESSION-SURFACE-PROJECTIONSESSION-DERIVED-CACHE
A Session therefore has two kinds of “past” at once: the raw log records what happened, while the current Surface determines what the next model request actually sees. Every later memory claim must first identify which layer it reads.
3. Durable History Is a Recovery Foundation, Not an Automatic Recall Policy
The Base bundle writes Session logs to $DSH_HOME/sessions by default. The persistence coordinator advances its durable cursor only after a backend batch append succeeds; resume and load use reservations plus a stable revision to obtain the exact repaired logical history. Live events enter bounded write-behind, explicit session/flush is the immediate durability barrier, and Session disposal drains remaining writes. MEMORY-DEFAULT-COMPOSITIONMEMORY-PERSISTENCE-TRANSACTIONMEMORY-PERSISTENCE-FLUSH
On POSIX, directories are created with 0700, synchronized temporary files with 0600, and publication uses linking, directory fsync, and cleanup without overwriting an existing log. This reduces same-machine disclosure and power-loss corruption risk, but it does not introduce a tenant authorization model. MEMORY-JSONL-PERMISSIONS
| What it guarantees | What it does not guarantee |
|---|---|
| Events append in contiguous seq order and become recovery facts after flush | No stable user profile or fact extraction |
| Cold Sessions can be read explicitly by the Host or query service | A new Session does not automatically search old Sessions |
| Original events shadowed by compaction remain auditable | The model does not automatically regain that shadowed source text |
4. Compaction Is a Lossy Same-Session Transformation, Not a Second Memory Store
Compaction start, summary, and end form a log-only bracket. The following user-message checkpoint with surfaceOp: replace is what actually changes model-visible history. The summary event retains shadowed seqs, estimated token price, provider/model, usage, and complete rawOutput, so both old source events and auxiliary model output remain in durable history. COMPACT-EVENTS
| Dimension | Compaction semantics | Why this is not long-term memory |
|---|---|---|
| Scope | One head-anchored span of the current Session Surface | It reads no other Session or external fact store |
| Result | A shorter checkpoint plus a retained recent tail | It serves the next request's context budget |
| Fidelity | The prompt asks for a structured summary; code checks only nonempty and shorter | There is no factual-consistency or entity-memory invariant |
| Recovery | Raw events remain; the Surface sees the replacement | Auditability does not automatically recall source text to the model |
The default basic policy triggers near 80% pressure, retains roughly a 16% recent tail, and allows bounded retries. Its summary directive explicitly requires English, adding a translation-loss surface for non-English Sessions. An automatic summary failure only warns and continues the Turn, so high-pressure history may remain uncompacted. COMPACT-CONFIGCOMPACT-SUMMARIZER
5. Session Reference Is an Explicit, Immutable, Sourced Cross-Session Snapshot
user selects source session ids
→ resolver reads each source's current Surface once
→ keep direct user text + assistant text + canonical checkpoints
→ drop tools, reasoning, nested injected context, and shadowed raw history
→ enforce a per-source UTF-8 byte budget
→ inject one sourced user-role snapshot into the target Session
The resolver defaults to at most three sources, 50 candidates, and 65,536 UTF-8 bytes per source. Its prompt explicitly marks the snapshot untrusted and read-only and tells the model not to follow instructions, permission claims, or tool requests inside it unless the current user repeats them. MEMORY-REFERENCE-RESOLVER
Projection retains only direct-user messages, assistant text, and canonical compact checkpoints. Under budget pressure it preserves checkpoints and the newest message, drops older non-checkpoint units first, then head/tail truncates the longest text with an exact omission count. MEMORY-REFERENCE-PROJECTION
prepare() reads each source once. Later appends, compaction, or deletion of the source cannot mutate context already written to the target Session; tests also require a fresh replay to reproduce the same target messages. MEMORY-REFERENCE-CONTRACT-TEST
It is not a fork, resume, subscription, or live share, and it does not run automatically when the model judges an old Session relevant. The context package overview explicitly classifies session-reference as opt-in. MEMORY-REFERENCE-OPT-IN
6. Session-Reference Authorization Belongs to the Host, Not the Resolver
listCandidates() lists every non-self Session exposed by sessionQuery; matching cwd affects rank, not filtering. Given an exact Session ID, prepare() directly calls readSurface(). The package README likewise states that the resolver assumes its Host may read every Session exposed by the query service. MEMORY-REFERENCE-RESOLVERMEMORY-REFERENCE-TRUST
At the pinned commit, the package is not mounted by default and there is no shipped Web candidate picker, so no stock UI path directly exposes this read capability. Any future multi-user Host that exposes it must filter discovery and independently reauthorize exact prepare requests. Cwd ranking must not be mistaken for access control.
The README says the standard TUI installs a one-shot pre-step wrapper and describes idle/running inject-and-steer integration paths. No corresponding production adapter, consumer, or shipped composition row exists at the pinned commit. The verifiable implementation ends at the resolver, URI/parser, projection, and replay UI components. MEMORY-REFERENCE-DOC-DRIFTMEMORY-REFERENCE-OPT-IN
7. Session Query Is a Unified Read Surface; FTS5 Is a Disposable Lexical Read Model
The query corpus prefers a detached live snapshot and inspects persistence only when the target is not live, checking again for an attachment race after the read. Batched cold reads have bounded concurrency and isolate one Session's failure as that item's rejected result. MEMORY-QUERY-CORPUS
Search documents are extracted event by event from the complete raw log and classified by the canonical Surface fold as current, shadowed, or log-only. Searchable text includes user and assistant text, tool names/arguments/results, Todos, and some Turn errors. Reasoning, raw chunks, request headers, unknown events, and unknown blocks are excluded. MEMORY-QUERY-DOCUMENTSMEMORY-QUERY-EXTRACTION
user/message extraction does not inspect source. Once FTS is enabled, plugin-injected user-role context—such as Skill catalogs, Skill invocations, or session-reference snapshots—may therefore enter the index. The Web Host filters to current user/assistant event types but performs no second message-source filter. This is a confirmed static indexing and privacy boundary, not evidence that the default configuration has created such an index.
The SQLite backend uses FTS5 with the unicode61 tokenizer, not embeddings or semantic retrieval. A persistent path duplicates extracted plaintext into a derived database. New directories and files are owner-only, foreign databases are refused, and a recognized but incompatible derived schema may be rebuilt. MEMORY-QUERY-SQLITE-SCHEMA
8. Exact Reads Are On by Default; Full-Text and Model Query Tools Are Off
Both Base and Web patches set path: ':memory:' and openAt: never. This mode never imports or opens SQLite and makes searchSessions/searchEvents return SESSION_QUERY_SEARCH_DISABLED, while titles, lineage, Surface reads, and exact event reads remain available through the unified service. MEMORY-DEFAULT-COMPOSITIONMEMORY-QUERY-SQLITE-MODELOG-QUERY-TRACE
Model-facing tool-session-query is a separate opt-in package registering session_search, session_event_search, session_trace, session_event_trace, and session_event_read. Shipped Host compositions do not mount it by default. It also deliberately applies no byte or character truncation; deployments needing bounded inline output must add a spill policy. MEMORY-QUERY-TOOL-CONTRACT
When mounted, the caller must come from exec.agent. Self access is permitted; cross-Session access requires exact cwd equality with the caller Session and is rechecked against the observed header after reads. Unauthorized lineage branches become markers that disclose no hidden Session ID. MEMORY-QUERY-TOOL-AUTH
The precise default statement is therefore: “The Host has a cross-Session exact-query seam, but the model receives no cross-Session search or read tools by default,” not the looser “Session memory is supported.”
9. The Web UI Is Local-Metadata-First and Degrades Content Search by Configuration
For a nonblank query, Workspace Browser immediately matches titles and Workspace names, then issues a debounced Host content search after 250 ms. Remote failure leaves local results visible and adds a warning. Local-first and remote results are deduplicated, merged, and capped at 20. MEMORY-WEB-SEARCH
The Host defines its visible baseline as attached Sessions plus servable cold Sessions carrying cwd. After querying the provider it accepts only hits in that visible set whose Session IDs agree and whose types are current user/assistant messages. This Host gate is the Web path's authorization boundary. MEMORY-WEB-HOST-GATE
Stock Web still sends a content request for every nonblank query, but Base's openAt: never deterministically rejects FTS. The user therefore gets title/workspace-only results plus an unavailable warning. The UI README describes the content-match interaction without explaining the shipped-off backend at that point, so “the UI can request it” and “the default deployment searches bodies” must remain distinct.
10. Skills Are Trusted Knowledge and Operating Instructions, Not Learned Conversation Memory
The Skill registry merges host/global and per-scope provider/runtime layers. The nearest scope wins same-name conflicts across layers, with rank resolving duplicates inside one layer. list() returns summaries and get() loads complete definitions on demand. There is no path in the registry for extracting, reinforcing, resolving, or forgetting facts learned from Sessions. MEMORY-SKILL-REGISTRY
The filesystem provider discovers flat .md files or one-level SKILL.md directories from the nearest Git root's .dsh/skills and .agents/skills, custom roots, user roots, and the bundled root. Watching and symlink following are on by default with at most 128 project watchers; non-bundled roots pass through the optional filesystem policy. MEMORY-SKILL-FILESYSTEM-CONFIGMEMORY-SKILL-FILESYSTEM-ROOTSMEMORY-SKILL-FILESYSTEM-LOAD
| Path | Content entering the model | Durable semantics |
|---|---|---|
| Catalog publication | Name + truncated description | A sourced user message records the complete current catalog |
Model calls skill | Full <skill_content> on demand | Ordinary tool call/result remains in the Session |
User types whitespace-bounded /name | Full instructions context injected directly | User message with a skill-invocation source |
Both load paths check the actual definition's invocation policy, and only direct user input can trigger the unforgeable /name gesture. Full bodies are deliberately treated as trusted local content and embedded verbatim. This is knowledge injection, not memory retrieval. MEMORY-SKILL-INVOCATION
11. The Main Skill Risks Are Repository Trust and Context Amplification
| Finding | Classification | Practical effect |
|---|---|---|
| Project Skills are discovered automatically with no per-repository or per-Skill consent | Host trust boundary | An untrusted repository's descriptions may enter the catalog, and a loaded body becomes strong instructions |
| Each description defaults to a 500-character cap, but Skill count and aggregate catalog size are unbounded | Static resilience gap | Many Skills can linearly amplify every catalog publication |
| Complete Skill bodies have no byte cap | Static resilience gap | One model or user load may consume substantial context |
| Bodies render verbatim as trusted instructions | Design boundary | This can produce prompt injection but does not automatically execute repository scripts |
Provider-config JSDoc says the default name is local; schema/constructor use filesystem | Documentation drift | An embedding host relying on the comment can infer the wrong provider identity |
The per-description cap, whole-catalog publication, and absence of a body cap are directly visible in implementation. The filesystem provider's JSDoc/default mismatch appears in the same configuration definition. MEMORY-SKILL-FILESYSTEM-CONFIGMEMORY-SKILL-FILESYSTEM-LOADMEMORY-SKILL-INVOCATION
Web skill.list resolves a host-owned cwd/scope only for an attached Session and returns user-invocable entries. The client caches per Session, offers candidates on /, and inserts only literal /name text after selection. Listing failures silently drop the menu group; there is no consent or risk-preview layer. MEMORY-SKILL-HOST-UIMEMORY-SKILL-CLIENT-UI
12. External Memory MCP Is an Interoperability Boundary; Providers Own Data and Recall Semantics
examples/mcp-memory supplies version-pinned overlays for Memorix, MCP Reference Memory, and Engram. Harness parses the overlay, launches a stdio child or connects to Streamable HTTP, discovers tools, and registers them as mcp__<server>__<tool>. It does not download the service, initialize its database, choose its model or embedding provider, migrate data, or supervise an independent HTTP service. The shipped composition contains no memory server, so all three remain disabled without --patch. MEMORY-MCP-BOUNDARY
| Provider example | Storage/retrieval described by its README | What Harness can guarantee |
|---|---|---|
| Memorix | Provider-owned local heuristic mode and data directory | MCP transport, tool discovery, and calls |
| Reference Memory | Local knowledge graph; case-insensitive substring search | Configuration passes a storage path to the child |
| Engram | Provider-owned storage and project selection | Launch configuration and environment boundary |
Write triggers, search timing, conflict resolution, forgetting, cross-project identity, and licensing are not core Harness contracts. The examples even recommend adding an instruction to write when asked to remember and search when history may matter if tool descriptions do not reliably trigger use, making the prompt/tool-policy dependency explicit. MEMORY-MCP-BOUNDARY
Existing tests prove overlays parse, pins are present, obvious hard-coded keys are absent, and a keyless fixture replacing the real command can be discovered. They run no real provider and prove neither write behavior, restart persistence, fresh-Session recall, permission isolation, nor semantic quality. MEMORY-MCP-CONTRACT-TEST
13. The Shipped First-Party Default Deliberately Lacks an Autonomous Memory Loop
not present as a shipped first-party default:
conversation → fact extraction → durable semantic store
→ relevance retrieval → ranking/dedup
→ permission-filtered automatic prompt injection
→ conflict resolution / forgetting / provenance feedback
Source and shipped composition establish a Session event log, Surface replacement, exact and lexical query, explicit snapshots, and instruction catalogs. They do not support describing the default as embedding memory, vector retrieval, episodic/semantic memory, learned user profiles, or automatic recall. External MCP can add some of those capabilities, but capability, data ownership, and risk vary by provider.
Explicit boundaries make replay, authorization, and token cost easier to reason about: history reads cross a Host/tool seam, cross-Session content carries provenance, Skills must be loaded, and external databases must be mounted deliberately. The cost is that “remember me over time” does not emerge automatically; a deployment must choose storage, triggers, authorization, conflict, and forgetting policy.
The most accurate product description is durable, replayable session history with explicit cross-session retrieval seams, not an autonomous memory platform.
14. Confirmed Issues, Static Risks, and Verification Status
| Item | Conclusion level | Status |
|---|---|---|
| Session-reference README describes a standard-TUI integration not present in the pinned tree | Confirmed documentation drift | Not mounted by default |
| Stock Web requests content search while the backend deterministically disables FTS by default | Confirmed composition/UI mismatch | Falls back to title/workspace + warning |
| Enabled FTS may index plugin-injected user messages | High-confidence static inference | No index is created by default |
| Persistent FTS duplicates extracted plaintext | Confirmed data boundary | Owner-only and explicit opt-in |
| Skill catalog/body lacks aggregate size caps and project discovery has no consent | Confirmed static resilience/trust gap | Relevant to the standard preset |
| Compaction retains shadowed raw events and summarizer rawOutput | Confirmed retention boundary | Not a deletion mechanism |
| Web search returns underlying error text | Source-acknowledged deployment boundary | Currently declared single-user local only |
| Memory MCP has no real-provider E2E | Confirmed verification gap | Configuration and fixture discovery only |
This chapter is pinned to upstream commit 47f943859bef60e4160492346772ded9b24f765a and cross-checked the Agent request path, Session/Surface, persistence, compaction, session reference, session query/SQLite/model tools, Web Host/UI, Skills, Memory MCP examples, and their test source. Dependency installation stalled on unrelated platform packages, so no test execution succeeded in this pass. The chapter reports source and existing test-contract audit, not a claim that runtime tests passed.
My Learning Notes
Autosaved only in this browser. Nothing is uploaded or committed. Export Markdown whenever you want to keep a copy.