Skip to content

Releases: LH8PPL/claude-memory-kit

v0.4.0

25 Jun 12:53

Choose a tag to compare

Added

  • Cross-agent install — cmk install --ide <agent> (Task 50; the v0.4.0 differentiator). The kit can now install into agents beyond Claude Code. --ide kiro wires Kiro's surfaces in one step, covering both the IDE (GUI) and the kiro-cli terminal: MCP registration (.kiro/settings/mcp.json), steering (.kiro/steering/cmk.md, inclusion: always), the memory skills (.kiro/skills/memory-search + memory-write), automatic IDE hooks (.kiro/hooks/cmk-capture.kiro.hook on agentStop → deterministic cmk hook stop capture; cmk-inject.kiro.hook on promptSubmit → recall), and a CLI agent-config (~/.kiro/agents/cmk.json + a chat.defaultAgent pointer in ~/.kiro/settings/cli.json) carrying agentSpawn→inject and stop→capture hooks. (These fire live — verified against a real kiro-cli session.) The hook command is platform-correct (cmd.exe /c cmk hook … on Windows, where Kiro routes hooks through WSL). The CLI agent is registered as the default agent so its hooks auto-fire — but guarded: if you already have a default agent, the kit installs a named cmk agent instead and leaves your default untouched (the install notice tells you how to opt in). Both hook surfaces drive the same cmk hook dispatcher and the same capture/inject core. Restart Kiro to activate the hooks; steering/skills/MCP are immediate. A --ide kiro install also drops a managed AGENTS.md block at the project root — Kiro's always-loaded instruction file (per kiro.dev), which the CLI agent-config's prompt points at. It does not write Claude-Code-only files (CLAUDE.md, .claude/skills/) on a Kiro install — Kiro can't read them. --ide agents-md emits the same managed AGENTS.md block standalone — a portable memory-awareness rung for the many tools that read AGENTS.md. The memory core (store / search / compression / CLI) is identical across agents; only the per-agent wiring differs. Default remains claude-code (unchanged). Built on a shared, tested config-write primitive (mutateAgentConfig — touch-only-our-keys, refuses to clobber a corrupt config) so each future agent stays thin.
  • Dual-agent projects — Claude Code and Kiro can share one repo. The installs are additive overlays: each cmk install [--ide <agent>] writes only its own agent's wiring and never clobbers the other's, and the shared memory brain (context/) is written once and reused. So a project used by both (two teammates, or one person switching tools) just runs both installs; --with-semantic set by either install is preserved by the other (it lives in the shared context/, not per-agent).
  • cmk uninstall --ide kiro — uninstall is now agent-scoped for Claude Code + Kiro. cmk uninstall removes the Claude Code managed surface; cmk uninstall --ide kiro removes the Kiro surface (its .kiro/ managed blocks, skills, IDE hooks, the AGENTS.md block, and the guarded ~/.aws CLI agent). Both stay conservative — they never touch context/ (the shared brain) or any content outside the kit's markers.
  • A memory delete-guardrail — the kit now blocks a command that would delete your memory before it runs. cmk install wires a PreToolUse hook (cmk-guard-memory) that inspects every shell command the agent is about to run and blocks it if it's a destructive command (rm, Remove-Item, git clean, git reset --hard, …) aimed at a memory path (context/, your ~/.claude-memory-kit persona tier, MEMORY.md/DECISIONS.md). A safe command, or a delete of anything else, runs normally — only a memory delete is stopped (with a clear reason). Wired for Claude Code (PreToolUse, Bash/PowerShell) — where it fires reliably. On Kiro, coverage depends on the surface: Kiro IDE and Kiro CLI V3 (2.9+) both rely on Kiro's own native "this is destructive, proceed?" confirmation (Kiro's IDE hooks can't be installed from a file, and Kiro CLI V3 redesigned its hook system — embedded preToolUse blocking was replaced by a permissions.yaml model; first-class V3 guardrail support is a planned follow-up). Fail-open by design: a broken guardrail never wedges your session, it just stops guarding. This came from a real data-loss incident — an accidental rm after a directory change deleted a repo's session/transcript memory; the guardrail makes that unrunnable.
  • Kiro hooks auto-run — no more "Run / Reject" prompt every turn. A --ide kiro install now pre-trusts the kit's OWN hook commands so Kiro runs them silently instead of asking you to approve each one. On the IDE side it writes kiroAgent.trustedCommands into the workspace .vscode/settings.json; on the kiro-cli side it sets the agent-config's toolsSettings.shell.allowedCommands — both scoped to the kit's commands only (cmk hook *, cmk-guard-memory, plus cmk remember/cmk search for the kiro-cli explicit path), never a blanket wildcard. Without this, the inject/capture/guard hooks prompted on every fire and "automatic memory" wasn't automatic (found by the v0.4.0 Kiro live-test gate).
  • Kiro IDE — MCP tools auto-approve so mk_remember and friends run prompt-free in chat. The IDE gates MCP tool calls through a different trust system than shell hooks, so the kit's memory tools (mk_remember, mk_search, …) used to pop a "Reject / Trust / Run" prompt every call. A --ide kiro install pre-approves the kit's 11 MCP tools via autoApprove in .kiro/settings/mcp.json. (mk_forget is safe to auto-approve: it previews and waits for a confirm token before deleting anything.)
  • kiro-cli (the terminal client) — fully working, and no cmd.exe console-window popup. The terminal client differs from the IDE under the hood: the kit's kiro-cli agent (~/.kiro/agents/cmk.json) enables the shell tool (tools: ['*'] — without a tools capability set a custom agent can't run any command) and uses the kit's cmk remember / cmk search commands for explicit recall/capture (pre-trusted, so they run prompt-free), while the agentSpawn/stop hooks do automatic capture+inject every turn. Automatic capture reads kiro-cli's own session transcript (~/.kiro/sessions/cli/, a different location + format than the Kiro IDE) and runs the same extract→promote pipeline as Claude Code — so a cross-project rule you state in a kiro-cli chat ("always use uv, in every project") promotes to your persona automatically, with no command. The agent does not load an MCP server (includeMcpJson: false) — kiro-cli launches every stdio MCP server in a visible console window on Windows, so turning MCP off for the terminal agent removes that popup entirely (the terminal uses the shell commands instead of MCP tools). The memory core and behaviour are identical to the IDE/Claude Code; only the in-chat surface differs. All verified end-to-end against a real kiro-cli session (the cross-project rule landed in the persona tier live).
  • Kiro now captures your prompts too — with the same privacy strip as Claude Code. On both Kiro surfaces, each prompt you send is now recorded to the session transcript (the searchable history tier) on the prompt-submit hook — matching Claude Code's behaviour — and anything inside <private>…</private> is stripped before it's written, so a secret you paste into a prompt never lands on disk. Previously the prompt-submit hook on Kiro only did recall (injected memory); it now does recall and capture.
  • Kiro kiro-cli now records large file edits, like Claude Code. The kiro-cli agent wires a postToolUse hook (scoped to the fs_write file-write tool) that appends a one-line edit summary (file=… lines=…) to the session buffer when you make a substantial edit (>50 lines) — the same observation Claude Code records on PostToolUse. It feeds the same memory pipeline, so the kit notices what you're actively working on.
  • Kiro IDE 1.0 — the kit's skills, hooks, and MCP tools run prompt-free, no per-tool approval. Kiro IDE 1.0 introduced a per-workspace trust store (~/.kiro/workspace-roots/<hash>/permissions.yaml). cmk install --ide kiro now pre-trusts the kit's own surfaces there — its shell hook commands, its 11 MCP tools, and its two skills (memory-write/memory-search) — so the agent never stops to ask "Load skill: memory-write — Allow?" or to approve a memory tool. Only the kit's own surfaces are added; your existing rules are preserved, and cmk uninstall --ide kiro removes only the kit's. (Verified live: the kit's full memory loop — inject, capture, observe, mk_remember, and the cross-project promotion — runs end-to-end on Kiro IDE 1.0 with no approval prompts.)
  • Kiro IDE 1.0 support — new hook format + a memory delete-guard and edit-observation in the IDE. Kiro IDE 1.0 replaced the old .kiro.hook format with clean per-hook .kiro/hooks/*.json files (v1). cmk install --ide kiro now writes both — the v1 files cmk-{capture,inject,guard,observe}.json (for Kiro IDE 1.0+) and the legacy .kiro.hook files (so older Kiro keeps working; on 1.0 they sit inert as "legacy", no double-fire). The v1 format unlocks the full hook set in the IDE — recall, capture, a delete-guardrail (PreToolUse, which can block a destructive command), and large-edit observation (PostToolUse) — so the IDE now reaches parity with Claude Code and kiro-cli. The v1 schema + the capture Stop trigger are confirmed against Kiro IDE 1.0's own hook-migration output; the remaining firing details are verified in a live Kiro IDE 1.0 session at the cut-gate.

Fixed

  • The Kiro CLI default-agent guard now tolerates a UTF-8 BOM in settings.json — it no longer clobbers your existing default agent. A ~/.kiro/settings/cli.json written by a Windows editor (or PowerShell Set-Content -Encoding utf8) carries a byte-order mark that broke the guard's JSON read, so it missed an existing chat.defaultAgent and overwrote the default with the kit's agent. Con...
Read more

v0.3.5

20 Jun 13:32

Choose a tag to compare

Fixed

  • Background memory compression no longer fails needlessly when Claude is slow, so recent.md / the archive stay fresh. The lifecycle compression jobs that run with no time limit (daily distill, weekly curate, the session-start catch-up roll) were using the same 50-second budget as the in-session compressor, and retried too quickly — so a slow claude --print window could time them out and leave consolidated memory stale (a real case left recent.md 4 days behind). They now get a 120-second budget and wait between retries, matching the no-deadline nature of those background jobs. (#209)

v0.3.4

19 Jun 21:26

Choose a tag to compare

Added

  • A documented update path + drift detection. New "Updating to a new version" guide for both install routes (README + QUICKSTART §9) — the npm two-step (npm i -g @latestcmk install per project) and the plugin flow (/plugin update/reload-plugins → re-bootstrap), with the Windows EBUSY "close Claude Code first" note. A new cmk doctor check (HC-9) flags a project whose scaffold is behind your installed cmk after an update, so the easily-forgotten per-project re-install never goes unnoticed.

Fixed

  • Compression now recovers from a transient Haiku failure instead of leaving the session buffer stuck. The lifecycle compression passes (daily distill, weekly curate, the lazy session-start roll) retry once with backoff on a transient timeout / overload, so an intermittent claude --print slowdown no longer strands now.md until the next session. Failures are also now logged with their exit code + reason for diagnosis. (#206)

v0.3.3

18 Jun 19:17
0b3be6e

Choose a tag to compare

Fixed

  • search(156): cmk search --scope decisions no longer shows a scary "unknown-scope" warning when semantic search is on. The decision-journal scope is keyword-only by design (the journal is a plain markdown file, not embedded), but with the hybrid default (after cmk install --with-semantic) it would print semantic default unavailable (unknown-scope:decisions) — or, with an explicit --mode, fail outright. It now recognizes the scope is keyword-only and just returns results, silently. The recall itself always worked; the alarming message is gone.
  • reindex(157): cmk reindex --full no longer crashes on a dual-written fact. A fact captured via cmk remember lives in both the working scratchpad and its archive file with the same id; a full reindex hit a UNIQUE constraint failed and aborted. The index now replaces by id with deterministic precedence (the archive copy wins), so reindex is robust and search results de-duplicate cleanly. Affects anyone who ran a manual cmk reindex --full; automatic indexing was unaffected.

Added

  • Tombstone recovery (155): cmk get <id> --include-tombstoned un-forgets a fact — for you, never for the AI. A cmk forget removes a fact from all recall, but its body is kept in the archive. You can now recover it: cmk get <id> --include-tombstoned reads the archive and returns the forgotten fact's body + when/why it was deleted. This is a human-only flag — the AI's mk_get tool stays tombstone-blind, so a fact you forgot never resurfaces in Claude's recall (a deleted fact staying deleted is the whole point). A live fact always takes precedence; recovery is a fallback only when the id isn't live.
  • Decision-journal recall (156): ask the AI how a decision evolved, not just what it is. The context/DECISIONS.md journal (added in 0.3.2) records every decision append-only — including the ones you later superseded or retracted. It's now recallable: cmk search "<topic>" --scope decisions (or mk_search with scope: "decisions") searches the journal for decision history — "what did we reject", "did X change", "why did we move away from Y" — and returns the superseded/retracted entries the live fact store no longer carries. The memory-search skill and the injected recall directive now point Claude at it for evolution/"what did we reject" questions, so you can just ask ("weren't we using Postgres? what changed?") and the AI consults the journal. This completes the decision-journal feature: it's no longer write-only.
  • Decision journal stays current automatically (159): no cmk digest needed. The context/DECISIONS.md journal now updates itself — every decision you capture is rendered into it at session end (and at the next session start for sessions that didn't close cleanly), so the journal is always current without you running any command. Previously it only existed if you ran cmk digest by hand; now it's automatic, like the rest of the kit's memory. (cmk digest still works as a manual refresh.)

v0.3.2

16 Jun 13:39

Choose a tag to compare

Fixed

  • search(153): natural queries with dots, hyphens, or version strings no longer crash. cmk search "v0.3" (or asking Claude to recall something via mk_search) used to fail with an FTS5 parse error because characters like ., -, and : have special meaning in the search engine's grammar. Queries are now auto-sanitized — each word that needs it is quoted for you — so v0.3, user-explicit, and section:search all just find results. Multi-word queries keep their "match all words" behavior, and an explicit "quoted phrase" you type yourself is still honored as a phrase search.

v0.3.1

15 Jun 04:46

Choose a tag to compare

Added

  • install: cmk install now scaffolds a .gitattributes that pins committed memory to LF line endings. Default Windows git (autocrlf=true) rewrites line endings at clone, which could make committed facts unreadable on a Windows checkout. The reader already self-heals (v0.3.0); this prevents the mangling at the source so your memory travels intact across platforms. Idempotent managed block (refreshed in place; everything else in your .gitattributes is preserved).

  • config(129): cmk config get / set / --show-origin — settings without hand-editing JSON. Now that --with-semantic writes a real user-facing setting (search.default_mode), you can read and change kit settings by dotted key instead of editing context/settings.json by hand: cmk config get search.default_mode resolves across tiers (local > project > user), cmk config set search.default_mode hybrid writes the project tier (or --local for the gitignored per-machine tier, preserving sibling keys), and cmk config --show-origin <key> shows every tier that defines it — which value wins and which are shadowed.

  • security(134): Poison_Guard screens more secret types. The secret catalog gained fixed-prefix provider tokens — GitHub OAuth/app/refresh + fine-grained PATs, Stripe live keys, Google API keys, GitLab PATs, npm tokens, and Hugging Face tokens — so a captured fact carrying one is rejected before it lands on disk. Pure additions (literal prefixes + length floors, no entropy heuristics); each ships a benign-near-miss test so ordinary prose is never falsely blocked.

  • memory(143): semantic near-duplicate detection at write time — memory rot dies at the door. With semantic recall enabled (cmk install --with-semantic), explicit captures (cmk remember / mk_remember) now compare the incoming fact against existing memory by meaning: "use uv not pip" vs "always install with uv, never pip" is caught even with zero keyword overlap, and routed to the conflict queue as a reviewable proposal — never silently dropped, never silently duplicated (cmk queue conflicts to resolve). Fully local (one embedding per capture, no API calls); degrades gracefully to the existing literal dedup when the embedder is absent. The detection threshold was measured against the real model, not assumed.

  • doctor(144): a memory-HEALTH section — content quality, not just plumbing. cmk doctor now ends with an informational read-only summary of what's IN your memory: total facts with the trust distribution, old-and-untouched facts worth a skim, possible duplicate pairs (literal token-overlap candidates — surfaced for review, never auto-removed), and pending conflict/review queue items. A healthy memory earns one quiet line; concerns appear only when non-zero, and the section never affects the doctor exit code.

  • ux(145): a session-start status line — the kit finally tells you it's working. Every session now opens with one user-visible line (e.g. claude-memory-kit: 23 fact(s) in context, 2 captured in the last 24h, 1 conflict(s) pending — cmk queue), shown via the hook's user-display channel: the model never sees it and it costs zero context tokens. An empty project says so honestly (memory is empty — capture starts this session) instead of staying silent.

  • install(141a): npm 12 readiness — the kit survives July 2026's install-scripts flip. npm 12 turns dependency install scripts off by default, which silently blocks the native build better-sqlite3 needs (the package then looks installed but search crashes at first use). Now: cmk install probes the binding up front and offers to fix it inline (one [Y/n], runs the documented --allow-scripts reinstall for you); cmk install --with-semantic passes --allow-scripts=onnxruntime-node itself on npm ≥ 11.16; a new doctor check (HC-8) backstops with the exact remediation command; the README documents the prepared-install one-liner.

  • import(142): cmk import-claude-md — onboard from the rules file you already own. New installs no longer start empty: one command parses an existing CLAUDE.md (default), .cursorrules, AGENTS.md, or any rules file into typed granular facts (user/feedback/project/reference, inferred from headings) through the kit's safe write path — Poison_Guard secret screening, home-path sanitization, dedup against existing memory — with write_source: imported, trust: medium, and real source_file/source_line provenance. Code fences and the kit's own managed block are never imported. --dry-run previews; apply requires explicit --yes.

Fixed

  • privacy: <private> content is now stripped on every write path, not just the prompt hook. Previously <private>…</private> was redacted only by the prompt-capture hook, so a fact written via cmk remember, mk_remember, or an import could carry the secret verbatim into committed memory. It's now stripped at the shared write boundary (terse bullets and rich fact files, all tiers) before anything touches disk — and the content-addressed id is computed from the redacted text, so dedup keys on what actually lands.

  • privacy: a <private> secret could survive in a fact's title when an 80-character title trim severed the closing tag. A fact's title is derived from the captured text and trimmed to 80 characters; if that trim landed inside a <private>…</private> span it broke the closing tag, the redaction regex no longer matched, and the secret leaked into the frontmatter title + the index. The strip now runs before the title is derived, so a trimmed title can never carry private content (verified end-to-end: title, filename, and index all redacted).

  • cmk repair --index now actually rebuilds the index. The repair path invoked the full reindex without the database handle it needs, so cmk repair --index / --all silently did nothing — masked because every test mocked the reindexer. It now opens the db and runs the real rebuild on the real path.

  • a failed index rebuild after a capture is no longer silent. cmk keeps context/memory/INDEX.md current on every write (best-effort). If that rebuild ever failed (e.g. an auto-extract hook killed mid-rebuild), the committed index could quietly fall behind the actual facts with no trace. The failure now records an audit entry, and cmk doctor (HC-4) already flags the drift with cmk reindex as the one-command fix — the fact itself is always safely on disk.

  • persona: cross-project traits you demonstrated (not just ones you declared as rules) now reach your persona — no stranded review queue. When the kit synthesized your cross-project style, traits stated as universal rules ("always use uv") were auto-promoted, but traits it merely inferred from how you worked (e.g. a layered-architecture preference you described but didn't declare as a rule) were routed to a review queue surfaced nowhere with no resolve command — so they silently stranded and never reached the persona that injects into new projects. The maintenance passes (daily-distill / weekly-curate) now auto-drain that queue: inferred persona candidates promote automatically (reversible with cmk forget if wrong), so your working style transfers to new projects more completely. (A deeper redesign — promoting by cross-project recurrence rather than phrasing — is planned.)

  • recall: questions about your project now reach memory instead of re-reading the code — however you phrase them. The memory-search recall skill used to fire reliably only on precise phrasings like "what did we decide about X", and crawled the code for structure/architecture/"where does X live" questions (its skip-clause wrongly treated those as live-code questions). It now triggers on the intent — "the answer might be something the project already established" — so oblique, roundabout asks recall correctly too ("why is everything so spread out across these folders?", "remind me what we settled on for X", "how come the route files are so thin?" all reach memory). The skill also fires on the per-prompt "memory available" hint, the skip-clause is narrowed to genuinely-live code, and the CLAUDE.md preamble + hint reinforce it. Verified live across precise, oblique, and vague phrasings — and confirmed it correctly stays out of the way for live-code actions and this-conversation questions.

Changed

  • internal: content fingerprints migrated from SHA-1 to SHA-256. The non-cryptographic content hashes used for dedup, change-detection, and provenance (source_sha1, the reindex diff key) now use SHA-256, consolidated into one shared helper. No user action needed; existing memory re-indexes itself once on first use after upgrade. (On-disk field names are unchanged for back-compat.)

v0.3.0

11 Jun 21:31

Choose a tag to compare

Fixed

  • portability(139): cloned projects recall their memory on Windows. Default git settings (autocrlf) rewrite the committed memory files' line endings on clone, which made every fact invisible to search until now — reads are line-ending tolerant and self-heal on the next write.

  • import(138): cmk import-anthropic-memory no longer breaks search. Imported bullets carried a non-standard provenance comment that failed the next index rebuild (search fell back to the stale index with a warning). Imports now write the canonical provenance shape.

  • memory(136): a long extraction can no longer write a corrupted fact. When a knowledge-dense turn produced more rich facts than the output budget, the last fact was silently truncated mid-word and stored as a stub. Clipped facts are now dropped (and counted in the diagnostic log) instead of written, and the budget is 4x larger so clipping is rare.

  • install(133): the memory-search skill is permission-allow-listed, so recall fires prompt-free (the skill shipped in this release without its allow entry — first invocation would have asked "Use skill?").

  • memory(132): organic auto-capture works again — the extractor no longer suppresses itself. Since v0.2.0, the fact extractor was shown the just-captured turn as "already saved" context (a write-then-read ordering bug), so it answered "nothing durable" for most organic conversation — explicit cmk remember captures and persona promotion were unaffected. The dedup snapshot is now taken before the turn is buffered. Found by the v0.3.0 release gate; if your context/MEMORY.md stayed suspiciously empty, this was why.

Removed

  • cmk view (a never-implemented stub). The command answered "not yet implemented" since v0.1.0 — removed rather than left promising vapor; a real memory viewer (for non-developer users) is parked as a designed v0.4 candidate. Read memory directly (context/MEMORY.md, context/memory/) or through cmk search.

Fixed

  • memory(124): cmk forget and fact merges keep INDEX.md current. Tombstoning or merging a granular fact now refreshes the markdown index in-band — previously the removed fact stayed listed (a dangling link) and cmk doctor's INDEX-accuracy check failed until a manual cmk reindex. Found by dogfooding the kit on its own repo.

Added

  • search(104.2 + 126): the session record is searchable — the last-resort recall tier. cmk search "<query>" --scope transcripts (and mk_search with scope) searches the session record — verbatim transcripts AND the compressed daily/weekly summaries — by keyword or meaning — the exact error message from three weeks ago, the command that fixed something, how a discussion actually went. Kept deliberately separate: normal searches never surface raw history; the memory-search skill reaches for it only when curated memory has no answer. Transcripts keep full history (unlike Claude Code's ~30-day session files), with growth bounded per turn at capture time.
  • transcripts(104.1): the kit's transcript now records what Claude DID, not just what it said. Each assistant turn's entry gains a compact Tools block — the commands run, files edited, searches made, with truncated results — extracted at capture time from Claude Code's live session record (which itself expires after ~30 days and never leaves your machine). Your committed context/transcripts/ becomes a durable, portable record of the actual work, ready to serve as the last-resort recall tier. Capped per turn so transcripts stay lean; privacy tags are honored everywhere.
  • hooks(75.2): a per-prompt "memory available" nudge keeps recall alive mid-session. Substantive prompts in a project with a memory archive now carry a one-line model-facing hint (via the existing UserPromptSubmit hook — no new hook, no extra process) reminding Claude that recorded memory exists beyond the session snapshot and naming the memory-search skill. Short prompts ("ok", "go") never pay it. With this, the recall trigger is complete: authority instruction at session start, an auto-invoked recall skill, and mid-session awareness.
  • skills(75.1): the memory-search recall skill — Claude now knows WHEN to search its memory. cmk install (and the plugin) ships a second skill alongside memory-write: an auto-invoked, read-only recall skill that fires on "what did we decide about X" / "have we seen this error before" / before re-deriving recorded project knowledge from code. It runs forked (raw archive expansions never bloat your conversation — only a curated, citation-backed summary returns) and teaches the filter-before-fetch ladder over the kit's existing search → timeline → get tools. The session-start snapshot is the hot index; this skill reaches everything behind it.
  • mcp(125): degraded recall is never silent. When a project's configured hybrid default can't run (embedder unavailable), mk_search now tells Claude the results are keyword-only and to suggest cmk install --with-semantic — so the degradation reaches the user instead of hiding. (The CLI already printed a stderr note; this brings the MCP surface to parity.)
  • install(46): one-flag semantic enablement — cmk install --with-semantic. Installs the local embedder, pre-warms the model (the one-time download happens during install, not on your first search), and flips the project's default search to hybrid — from then on, plain cmk search and Claude's mk_search recall by meaning with no flags. --no-semantic pins keyword-only; if the embedder is ever unavailable, a configured hybrid default degrades gracefully to keyword instead of failing.
  • search(65): semantic + hybrid recall are REAL — ask in your own words, get the right memory. cmk search --mode=semantic|hybrid (and the mk_search MCP tool Claude drives) now run an embedded vector backend: sqlite-vec inside the kit's existing index + a local ONNX embedder (Xenova/bge-base-en-v1.5), chosen by a measured bake-off — R@5 0.941, paraphrase recall 1.000 on the kit's recall benchmark (vs 0.176 for keyword-only). Paraphrase queries that keyword search structurally misses ("where do credentials go" → the 1Password fact) now hit. The embedder is optional (~260 MB once, model downloads on first use): without it, semantic/hybrid degrade to a clear install hint and keyword search is unchanged; CMK_DISABLE_SEMANTIC=1 opts out entirely. Zero API calls — everything runs locally.
  • inject(75.0): the session-start memory snapshot now opens with an authoritative-memory instruction. Every non-empty injected snapshot leads with a fixed preamble telling the agent the injected memory + cmk search are the ground truth for documented knowledge and prior decisions — "when injected memory contradicts your assumptions, injected memory wins; never treat a question as novel when the answer is already in your prompt" (adapted from memory-os Layer 07). Fixes the cold-open failure where the agent re-derives from code what its memory already answers. The scaffolded CLAUDE.md gains a matching one-line Authority rule. Existing installs pick the preamble up automatically on upgrade — it is generated by the hook, not scaffolded.

v0.2.4

09 Jun 17:56

Choose a tag to compare

Removed

  • Dropped the stale memsearch + Milvus scaffolding (Task 120). The kit ships keyword-only and never actually used memsearch, but cmk doctor had two memsearch checks (HC-1 "installed" + HC-7 "reachable") and the install shipped a milvus-deploy Docker stack + a nightly-index cron + "install memsearch" setup docs — confusing users into thinking a semantic backend was required. All of it is gone: cmk doctor now runs 7 checks (HC-1..HC-7) instead of 9, and --mode=semantic/--mode=hybrid report the Layer-5b backend is "not yet shipped" (the choice is deferred — design §9.3.1; the semanticBackend extension seam is kept).

v0.2.3

09 Jun 10:49

Choose a tag to compare

Added

  • cmk remember --from-file <fact.json> and cmk remember --json (stdin): capture a rich fact as a JSON object read from a file or piped in, so backtick / $() / quote-heavy Why/How content never rides the shell command line. Fixes the silent corruption where bash command-substitution ate backtick spans in --why/--how arguments (D-81). (Task 108a)

  • Claude can now do every memory operation through conversation — the MCP tools reach parity with the CLI (Task 108b). The MCP surface (the tools Claude drives on your behalf, so you never type a command) gained:

    • Rich capturemk_remember now writes a structured Why/How fact file (not just a one-line bullet) when given why/how/title/type, matching cmk remember --why/--how.
    • mk_trust — change a fact's trust level (low/medium/high).
    • mk_lessons_promote — carry a project-tier fact to your cross-project user tier so it applies in every project.
    • mk_forget — tombstone a fact (audit trail preserved). Destructive, so it's two-step: the first call previews exactly what would be removed and returns a confirm token; Claude must call again with that token to delete — nothing vanishes without you seeing it first.

    Plus the review/conflict queues are now MCP-drivable too — mk_queue_list shows what's pending and mk_queue_resolve clears it (promote/discard a review item; keep-old/keep-new a conflict) — so Claude can resolve a queued capture in conversation instead of you running cmk queue.

    And the CLI gained the read verbs the MCP tools already had, so the surfaces match both ways: cmk get <id…> (full fact bodies + provenance), cmk timeline <id> (what was captured around an observation), cmk cite <id> (a canonical citation link), and cmk recent-activity (recent changes in a time window). Both surfaces run the same shared core, so they always return the same thing — and a build-time guard fails CI if a memory op ever exists on only one side.

  • cmk install now registers the MCP server, so Claude can use those tools with zero friction (Task 108b). Install writes .mcp.json (the cmk stdio server) and allow-lists mcp__cmk__* in .claude/settings.json, so the moment you open Claude Code it can capture/recall/forget through the tools above without a per-call approval prompt. This sidesteps a real Claude Code permission edge where a cd … && cmk … compound command always re-prompts — running the same op as an allow-listed MCP tool is prompt-free. The memory-write skill now prefers those tools too (falling back to the cmk CLI when the server isn't connected). --no-hooks skips this wiring.

  • Steer your memory in plain language — "forget that" and "trust this / that's not important" now work in conversation (Task 117). The memory-write skill recognizes these as triggers and routes them to the safe path: "forget about X" → tombstone it (mk_forget, with a preview-then-confirm step); "trust this" / "that's important" → raise its trust; "that's not important / I'm not sure" → lower it (mk_trust). Trust drives what gets loaded first and what ages out, so you can curate your own memory without ever touching a file or typing a command.

Fixed

  • cmk persona generate no longer times out on a real project (Task 111). On a project with substantial memory, generating your cross-project persona failed with claude --print did not return within 50000ms — the classifier was fed your entire project memory as one unbounded prompt, and the timeout was sized for the 60-second session-end hook even though the command you run by hand has no such limit. Now the corpus is byte-capped (whole facts only) so the prompt can't balloon, and the explicit command (and the weekly curate pass) get a generous timeout since nothing is waiting on them. If it ever does time out (a transient API slowdown), the error now says so and tells you to re-run.
  • cmk forget (and any removal) now disappears from search automatically — no manual cmk reindex (Task 110). A forgotten fact was tombstoned correctly, but its search-index entry lingered, so it kept showing up in cmk search (and could resurface in context) until you manually ran cmk reindex. A memory you told the assistant to forget reappearing is a trust failure, not cosmetic. Now the index self-heals: the boot reindex (which every read path runs) prunes entries for any source file that no longer exists, and forget reindexes in-band so the fact is gone the instant it returns — whether you forget via the CLI or by telling Claude in conversation (the mk_forget tool). In-place changes like cmk trust and adds like cmk lessons promote already propagated; this closes the deletion gap.
  • cmk register-crons now works on Windows and macOS — it had been broken since v0.1 (Task 109). Registering the daily-distill + weekly-curate background jobs failed on Windows (even --dry-run, exit 2) because the kit built the scheduler command as a pre-quoted string and then rejected its own inner quotes — so the cron jobs could never register. It now hands the arguments to schtasks directly as an args array (no shell re-parsing), so the quoted absolute paths survive intact; macOS got the sibling fix (the launchd job no longer bakes literal " into the program path). Linux was already fine. (Skipping cron remains fully supported — the kit falls back to compressing at session start.)
  • Stale pre-1.0 messaging cleaned up across the unified MCP + CLI memory surface (Task 121, D-102). After the CLI and MCP cores were merged (108b), a live run surfaced a hardcoded mk_remember in v0.1.0 only writes to tier P error plus other drifted v0.1.0/v0.1.x strings, and the MCP server reported a hardcoded version. Now: requesting a non-project tier (U/L) on a capture returns a clear note that it was saved to the project tier (and how to promote it cross-project) instead of erroring; the MCP server reports its real package version; and the user-facing tier/citation messages are version-agnostic.
  • Every memory capture now leaves an audit-log entry (Task 123). Rich fact writes (both your explicit remember and automatic auto-extract) were silently skipping the operational audit trail on the create path — only duplicate-skips were logged. Now each create is recorded in .locks/audit.log with its tier, provenance, and trust, so the audit trail the kit promises is actually complete. Also: orphaned auto-extract temp files are now swept instead of accumulating.

Security

  • Vulnerability reporting now goes through GitHub private Security Advisories (Task 123). SECURITY.md routes reports through the repo's Security tab (private, with coordinated disclosure + reporter credit) instead of a direct email.

v0.2.2

07 Jun 18:43

Choose a tag to compare

Added

  • Automatic memory now writes rich Why/How fact files, not just one-line bullets (Task 103). The per-turn auto-extract pass — the one that runs in the background on every assistant turn and is immune to which memory tool the model happens to reach for — now synthesizes structured fact files (a titled record with a breakdown body + Why + How to apply) for durable project knowledge: your setup/config, project conventions, completed workflows, and tool quirks. Lighter signals (corrections, preferences) still land as terse MEMORY.md bullets. Before this, only the explicit cmk remember --why/--how produced rich files — so if the model saved to Claude Code's built-in memory instead, you lost the rich tier. Now rich capture rides the automatic path, at trust: medium (a later explicit cmk remember still supersedes), screened by the same secret-guard + home-path sanitization as every other write, and searchable via cmk search.

Fixed

  • The scaffolded CLAUDE.md reads clean — no stale version or dead links (Task 107). A fresh cmk install was dropping a CLAUDE.md block that still said "v0.1.0 is under active development", undercounted the health checks ("HC-1..HC-8" — there are 9), and carried relative links to docs/adr/ and specs/… that resolve inside your repo (where they don't exist). It now reads as a clean runtime contract with external doc links. Also: the managed .gitignore block's version marker tracked the install version instead of a hardcoded v0.1.0, and a stray internal Task 92 reference was removed from the gitignore comment.
  • A session-buffer rollup can no longer drop a turn it races with (Task 106). When the kit compresses your live session buffer (now.md) it takes ~5–10s (a background Haiku call) and then clears the buffer. If your session wrote a new turn during that window, the old behavior could clear it away with the rest. The kit now claims the buffer with an atomic file-rename before compressing, so anything written meanwhile lands on a fresh buffer and is never touched. (This mattered more after Task 105 started rolling at session start, when a new session is actively writing.) Verified with a concurrent-write test + a live end-to-end run.
  • Session memory self-heals at the start of a new session, not only on a clean exit (Task 105). The kit compresses your live session buffer (now.md) into a dated daily file at session end — but Claude Code only fires the session-end hook when you cleanly close the window, not when you start a new chat in the same window. So if you live in one long-running window, now.md could grow without bound and the rolling daily/weekly summaries never built. Now, at session start, the kit notices a now.md left over from a prior session and rolls it forward in the background (detached, so it never slows your session start). The compression no longer depends on a clean exit. (Both paths run and are idempotent.)
  • Hook bins no longer hang when run manually without piped input (Task 101). v0.2.0 fixed this for the SessionEnd bin (cmk-compress-session, Task 100), but every other lifecycle hook bin — cmk-capture-prompt, cmk-capture-turn, cmk-inject-context, cmk-observe-edit, and the plugin's cmk-version-check — shared the same blocking stdin drain: run one by hand (e.g. to debug) without redirecting input and it would hang forever waiting for an end-of-input the terminal never sends. They now detect an interactive terminal and skip the blocking read, so a manual run finishes instead of stalling. No change as a real hook — Claude Code still pipes the payload exactly as before.