dsh-hippocampus
Cross-session project memory for DeepSeek Harness — capture / consolidate / recall, keyword + optional local-Ollama semantic search. Inspired by magic-context.
- Stars
- 0
- Language
- JavaScript
- Created
- Aug 26, 2026
- Updated
- Aug 26, 2026
Introduction
dsh-hippocampus
A self-managing cross-session project memory layer for DeepSeek Harness (DSH) — the Capture / Consolidate / Recall loop of cortexkit/magic-context, reimplemented as a native DSH plugin.
Status: feature-complete and verified against real workloads. Memory tools, prompt injection, event-driven auto-capture, consolidation subagents, CJK-tokenized keyword search, optional semantic search (local Ollama or OpenAI-compatible), compaction checkpoints + memory-aware compaction summaries, a signal-gated retrospective capture pass, and a settings page inside the DSH web UI.
Background
DeepSeek Harness (DSH) is a
Cordis-based agent harness: every capability is a plugin row in a cordis.yml
composition, services/events/slots are the extension primitives, and dsh web
serves the GUI. This project ships as one host-composition row, so every session
of every preset gets the memory layer — no per-session mounting.
magic-context is an excellent memory system for OpenCode/Pi-style harnesses. This project is a from-scratch native reimplementation of its ideas on DSH primitives — none of its code is used.
How it differs from magic-context
| magic-context | dsh-hippocampus | |
|---|---|---|
| Scope | Memory layer plus context management (historian compartments, m[0]/m[1] cache-stable transform, byte-exact replay) | Memory layer only — DSH owns compaction and context shaping |
| Storage | SQLite (context.db, FTS5, vector BLOBs) | DSH storageDomain JSON snapshots (whole-snapshot RMW, serialized writes) |
| Retrieval | sqlite-vec / local ONNX / remote embeddings | Intl.Segmenter CJK tokenization + scored ranking; optional local Ollama or any OpenAI-compatible /embeddings; in-JS cosine |
| Capture | Historian fact promotion tied to its compartment engine; dreamer cron tasks | Regex heuristics + a signal-gated retrospective pass whose child writes through idempotent tool calls; pre-compaction trigger slot |
| Compaction | Replaces the host's compaction entirely | Observes and enriches DSH's native compaction (checkpoint capture + memory-aware summaries) without touching ownership |
| Packaging | Multi-package monorepo (TS + Rust) | Two plain-JS function bodies (src/host.js, src/client.js) derived to deployable ESM by one script — zero build dependencies |
The full design rationale — scope boundary, pipeline details, and platform
implementation notes — lives in DESIGN.md.
Features
- Durable memories —
ctx_memory(write / list / delete) across five curated categories plus auto-managedCHECKPOINTentries; scoped to a stable project identity so memory follows the project, not the session. - Recall —
ctx_searchover memories and notes: CJK-aware token scoring, verbatim-substring strong hits, optional semantic cosine, plus cross-session history search when the deployment enablessession-query-sqlite. - Prompt injection — top-importance memories are rendered into every model turn (bounded by count and character budget).
- Auto-capture — decision/constraint phrasing in user messages and writes to well-known config files become memories; a content classifier keeps machine-originated texts (harness snapshots, reminders, own child reports) out.
- Retrospective capture —
/ctx-retroscans buffered recent user messages; correction/restatement signals dispatch one subagent that distills durable facts and writes them itself via idempotentctx_memorycalls. Timer and pre-compaction triggers included, with cooldown and single-flight latches. - Dreamer consolidation —
/ctx-dreamspawns a continuable subagent that dedupes/curates memories and reports back into the session. - Compaction-aware — compaction summaries are stored as searchable CHECKPOINT memories (T0), and durable memories are injected into the summarizer input so summaries stay continuity-aware (T1).
- Settings page — a Magic Context section in the DSH web settings: semantic search on/off, provider switch (local Ollama / OpenAI-compatible endpoint), endpoint/model/key, Ollama detection and service start, injection budgets, capture toggles — all live (no restart needed).
Requirements
- A DSH deployment with the web profile (
dsh web). The plugin targets the Node runtime DSH ships (v24-class); no extra dependencies. - Optional, for semantic search only: Ollama with a
multilingual embedding model (
ollama pull bge-m3, ~1.2 GB). Without it the plugin runs fully keyword-only — every failure path degrades silently.
Deploy
node sync.mjs # derive index.mjs + client.mjs + package manifest into the profile
# (~/.dsh/profiles/web/node_modules/@local/dsh-hippocampus/)
then register one insert row in the same profile's patch layer
(~/.dsh/profiles/web/cordis.patch.yml):
- insert:
- id: dsh-hippocampus
name: '@local/dsh-hippocampus'
and restart dsh web (ESM is cached per process). sync.mjs validates both halves
(node --check + import smoke test) before writing anything.
Why a derived file? The loader imports the row as a real ES module while
src/host.js/src/client.jsare written as plain function bodies (also valid as dynamic-plugincode.host/code.clientdefinitions). Never bare-copy the sources — a top-levelreturnis fatal under ESM.
Configuration
Open Settings → Magic Context in the web UI. Everything applies live:
| Group | Knobs |
|---|---|
| Semantic search | enable · provider (Ollama / OpenAI-compatible) · endpoint · model · API key · connection probe · index rebuild |
| Local Ollama | status detection (reachable / installed / missing) · start background service |
| Injection & capture | injection count cap · character budget · auto-capture toggle · retrospective auto-trigger toggle |
Settings persist in the memory domain (mc:cfg) and are merged over defaults at
read time. The API key never appears in GET responses, and write routes only accept
loopback peers.
Repository layout
dsh-hippocampus/
├── DESIGN.md # Design doc: scope, pipelines, compaction integration,
│ # config model, DSH static-plugin implementation notes
├── src/
│ ├── host.js # Host half (plain JS function body): tools, injection,
│ │ # capture listeners, retrospective, /mc-api bridge, T1 wrap
│ └── client.js # Client half (plain JS function body): Magic Context settings page
├── sync.mjs # Derives deployable ESM for both halves + package manifest; validates
├── package.json
├── LICENSE # MIT
└── README.md
Verification highlights
Exercised against real workloads rather than mocks:
- Durability and idempotent writes survived process restarts and plugin updates.
- A real
/compactproduced a checkpoint memory end-to-end; the summarizer's own output confirmed the injected memory block was present in its input. - Zero-overlap paraphrase queries ("怎么发布上线" vs a memory that only ever says "部署必须经 sync.mjs") are recalled by the semantic channel alone (sim ≈ 0.52) — unreachable by keyword scoring by construction.
- Machine-originated texts (runtime snapshots, harness reminders, child reports) are kept out of the memory pipeline by a content classifier — in live traffic, not just in tests.
Notes & limitations
- Semantic search adds one embedding call per query (~6 s warm CPU inference for
bge-m3; the request pinskeep_alive: 30mso idle gaps don't re-pay the ~41 s cold load). Timeouts are split per scenario (query 8 s / probe 60 s / sweep 120 s). - Cross-session history search requires enabling
session-query-sqlitein the profile patch layer (shipped opt-in withopenAt: never). - Sub-agent reports spliced into a session are filtered by signature and structure;
novel prose-shaped reports remain a theoretical capture risk — delete stray rows
via
ctx_memory deleteif one ever slips through. - Concurrent mutations to a storage domain must be serialized: the JSON store persists whole snapshots (read-modify-write). All automatic writes in this plugin go through one promise chain for exactly this reason.
- The storage layer duck-types domain
valueSchema(only.parse/.safeParseare called), so the plugin body needs nozoddependency.
License
MIT — see LICENSE.