About this project

ohmyboring is a self-hosted personal memory system for coding agents. It captures how you solved things in Claude Code, Kimi Code and eligible Codex sessions, distills each session into a curated markdown note stored in a local vault, and brings those notes back when you ask "how did I do this last time?". Everything runs locally: embedding and synthesis go through a local LLM server (Ollama, LM Studio, or another OpenAI-compatible endpoint), with no external APIs or tokens. How memory gets in: - Automatic on session end: a SessionEnd hook distills the transcript and stores it; a paired UserPromptSubmit hook injects up to three relevant past snippets into new prompts, each carrying settled claims. - Codex worker: since Codex has no SessionEnd hook, a host worker scans ~/.codex/sessions every 20 minutes and ingests eligible transcripts. - Backfill: `make collect` seeds an otherwise-empty vault from past Claude Code history (newest-first, idempotent, N per run); `make collect-kimi` does the same for Kimi Code. - Mid-session: `make distill-now` re-distills the current transcript, and `make remember M="..."` saves an explicit note. Memory is markdown-first: plain, human-readable, git-diffable notes in vault/wiki, which can be opened directly as an Obsidian vault for graph view, backlinks, tags and full-text search. An optional pgvector accelerator (BORING_VECTOR=on) adds similarity search and GraphRAG when scale calls for it. Architecture separates a fast, LLM-free read door (`make ask`, recall.py, MCP recall) from a gated write door (distill-session.py calls the local LLM and writes through a deterministic remember MCP tool). A duplicate gate skips duplicate notes but lets a richer note rewrite the same wiki file. A Rust-side typed workflow graph contract in drudge/src/workflow.rs defines the node/edge vocabulary for session discovery, distillation, verification, repair, remember, marker update, event logging and readiness projection, while Python hooks and workers still perform host I/O. Configuration lives in boring.json (from boring.example.json): note language, LLM provider/base_url/model/embedding model and dimension, repo origin rules, and agent transcript adapters. Switching backends is one config block; `make up` dispatches to provider-specific bootstrap scripts. Changing the embedding model changes the vector dimension, so llm.embed_dim must be updated and `make reset` run. A .env file holds secrets and runtime overrides such as BORING_VECTOR, LLM overrides, distillation clamps, recall claim counts and relevance measurement, event sink/spool settings, readiness windows, and an owner token for write calls. Operational tooling includes `make verify-llm` (provider, model ids, embedding dimension), `make doctor` (stack, hooks, Codex worker/queue, latest ingest), `make readiness` (strict pre-briefing gate), `make peek` (read-only local page showing which notes recall injected and how far the retriever reached), and `make usage` (token and model usage folded from local transcripts). A PII/sensitive-data gate in vault/rules/pii.yaml supports block, redact and flag actions with per-line exemption markers. Optional integrations include a Slack assistant and Hermes cron workers for morning briefs. Requirements are Docker, Python 3, jq, curl, git, make, and a local LLM server. A fresh clone starts with an empty vault, so day-one recall finds nothing until history is backfilled. The project is MIT-licensed and documents local model pairing guidance by machine RAM, benchmark commands, and measured distillation/embedding behavior.