-
Notifications
You must be signed in to change notification settings - Fork 0
Design Decisions
This page records the architectural decisions that are considered settled for this project — changing any of them needs the owner's sign-off, not just an agent's judgment call. It also lays out why the project exists at all instead of using an off-the-shelf memory tool.
| # | Decision | Rationale |
|---|---|---|
| D1 | Source of truth = a git repo of hand-curated Markdown. Sacred. Never auto-written. | Auditable, versioned, owner-controlled. Prevents memory-rot. |
| D2 | Growth via append-only journal + manual promotion ("Model B"). Agents append dated raw notes to a journal buffer. They never touch curated files. The owner periodically promotes journal notes into curated Markdown by hand. | Gets self-extension without letting agents corrupt the source of truth. The promotion gate is the owner's control point. |
| D3 | Protocol = remote MCP server, not plain REST. One Cloudflare Worker exposes MCP tools. | The consumer is Claude everywhere (Code, Desktop, browser). MCP is auto-invoked by the client, which kills the manual copy-paste that is the actual pain point. Collapses "filesystem-having vs filesystem-blind" client differences into one mechanism. |
| D4 | Two tool classes with separate auth: read and write. A read token serves context; a distinct write token gates journal appends. | A read leak exposes the owner's context (bad). A write compromise would let an attacker poison the memory across every session (worse). Separate keys plus manual promotion contain both. |
| D5 | Engine and content are separated. The machinery is public-shareable; the owner's actual context is private. Curated Markdown lives in a gitignored content/; the repo ships content.example/ templates. |
Lets the repo go public on GitHub without leaking the owner's resume/goals. |
| D6 | Deploy target = Cloudflare Workers + KV. | No warm server to manage, low latency, and the owner already has a domain on Cloudflare. |
| D7 | A thin personal Skill sits on top of the MCP connector, steering Claude to call get_context at session start. |
Skill = how to use the memory; MCP = what the memory is. Standard pairing — keeps the "always fetch this at the start" instruction out of the server itself. |
See Architecture for how D1-D6 map onto actual code, and Security-Model for the concrete enforcement of D2 and D4.
Personal memory layers for LLMs already exist and are, in most respects, more mature than this project. Worth naming honestly rather than pretending they don't exist:
- OpenMemory MCP (mem0) — self-hostable, user-owned memory across MCP clients, with a dashboard, per-client ACLs, and audit logs.
- mem0-mcp-selfhosted — self-hosted memory for Claude Code with an optional knowledge graph.
- Claude Code's own Auto Memory / Session Memory — already extracts and carries forward notes and summaries between sessions, with no extra infrastructure required.
If the goal were only "stop re-pasting who I am every session," any of these would work today, with less code to maintain.
Those tools are vector-store-backed: they extract facts automatically and retrieve them by semantic similarity. That design has a known failure mode, described plainly by one such tool's own author: self-hosting fixes where memory lives, but it does not fix what happens when a stored fact stops being true. If an agent writes "prod runs on Postgres 14" and it later becomes 16, both rows sit in the store, and similarity search hands back whichever scores higher — usually the older, more reinforced one. Nothing retracts a fact.
That failure mode maps directly onto how a personal or research context actually changes: current projects, course load, and priorities shift term to term. A system that quietly keeps surfacing last term's status alongside this term's is worse than no memory at all, because it looks authoritative while being wrong.
context-kernel avoids this by construction, not by tuning the retrieval:
- The curated store is hand-edited Markdown, not extracted facts in a vector index. Nothing becomes "memory" without a human writing or approving the sentence.
- Agents can only append to a disposable journal (D2). They cannot edit curated context, so they cannot silently overwrite or contradict it.
- Promotion is a manual, human-run step. Stale or superseded content is retired because the owner removes it, not because a retrieval score happened to favor the newer entry.
This is less automatic than a vector-memory tool, and it does not do semantic search over history — there is no "find everything ever said about topic X" query. It optimizes for the memory being trustworthy over it being self-maintaining. For a single owner curating context about themselves, that tradeoff is deliberate: the volume of curated content is small enough that hand-editing a handful of Markdown files periodically is not a burden, and the payoff is that nothing in the store is ever stale without the owner knowing it.
A few items from the original build brief were flagged as things to confirm rather than decide unilaterally:
-
License choice. MIT was suggested; a
LICENSEfile exists in the repo, but the owner should confirm the final choice is intentional. -
Auth handshake. Resolved in favor of a static bearer token (see Security-Model and
src/worker.ts's inline reasoning) after checking Anthropic's current MCP connector docs — OAuth is only required for servers proxying a third-party provider, which does not apply here. -
list_journalscope. Resolved write-token-gated — see Security-Model.