# Engram — context for Claude Code

**What this is:** a graph-based, durable, inspectable long-term project memory for AI coding assistants (Claude Code first). Local-first, user-owned, graph-first UI. The **reasoning/decision memory** layer (why/decided/what-bit-us) — not a code-structure graph; the wedge is the editable IDE-embedded graph pane + conflict surfacing + local. The line since 0.8.0: *the most powerful and feature-rich inspectable graph long-term memory for software development with AI agents, based on reproducible research.*

**THE GRAPH IS THE MEMORY OF RECORD — this file is only a keyword index.** The session brief is auto-injected; `search` engram before any non-trivial work and follow the write-verdict protocol. Details, rationale, gotchas, and the full history live in this repo's graph (`.engram/graph.tepin`, daemon on 8787) and the eval workbench graph (`eval/.engram`, project `eval`, scientific ontology Claim/Method/Question/Finding/Source/Task). PLAN.md was retired 2026-08-04 (merged here); `PLAN §…` references in code comments point at git history.

## Hard rules (locked — don't relitigate without reason)
- Open-source, MIT; optimize for docs & DX. Product name **"Engram Alpha"**, binary `engram-alpha` (repo/plugin namespaces stay `engram`; JetBrains package `dev.techtheist.engram` — don't rename).
- **Rust** backend (rmcp, rusqlite bundled, sqlite-vec, fastembed, tepindb) — no Node runtime dep. **Vue 3.5 + TS + Vite + Bun**, Pinia, Tailwind 4, Vue Flow; `bun run lint` / `lint:style` in `frontend/`.
- Embeddings/models **local-only**; **no LLM in the daemon, ever** (encoder-only mechanisms); models nominate, people judge.
- **Retrieval changes cite a measured `eval/` run or they don't ship** (since 0.8.0).
- **9 node types (8 + Tombstone since 0.9.0) / 7 sentence-shaped verbs** on the default ontology; no new types, no `relates_to`; durability governs staleness; high-value edges are `replaces`/`conflicts-with`. Per-graph ontology/policy config exists since 0.7.0, but THIS repo's graph stays on the default ontology permanently.
- **Hard delete is user-only** (pane); MCP deliberately has no delete/register/pin tools. Writes are silent; transparency is the pane. One workspace version for every crate, stamped from the tag; `claude-plugin/.claude-plugin/plugin.json` must match (test-enforced).
- Multi-user & repo sync: **out of scope permanently** (future enterprise product). Dogfood on the **aggressive** skill variant (relaxed is the user default). Eval ladder max **1500 notes**.

## Where things go
`crates/engram-core` (engine, Store trait + sqlite/tepin drivers, policy, config, cortex) · `crates/engram-mcp` (rmcp tools) · `crates/engram-http` (axum API + embedded pane) · `crates/engram-cli` (`engram-alpha`: serve/mcp/doctor/setup/migrate/stop) · `frontend/` · `eval/` (engram-eval bench) · `engram-jetbrains/`, `engram-vscode/` · `skills/engram/{aggressive,normal,relaxed}` + `claude-plugin/` (verbatim copies, sync-tested).

## Workflows & sharp edges
- **Pane/daemon rebuild: `scripts/deploy-pane.sh` only** (never hand-chain build/install/restart); after any redeploy, `/mcp` reconnect — live stdio sessions keep the OLD binary and stale tool descriptions.
- **Release:** CHANGELOG section (one `## v<version>` per release) → push → `gh workflow run draft-release.yml -f version=X.Y.Z` → publish the draft. Bump the graph's working version (`set_version`) when a cycle OPENS, not at release.
- **Eval:** `cargo run -p engram-eval --features fastembed -- --series|--ladder|--sizes N|--tricks|--posttune|--floor|--bench|--chains|--window|--longmemeval s` — receipts in `eval/results/`; `--distractors 0` = question-everything mode; `--longmemeval` downloads SHA-pinned into `eval/data/` (gitignored).
- Search-before-write; every write response is a verdict (matched → merge, suspects → judge now, warnings → check canon).

## Chronicle (slim — search the graph with these keywords for the full story)
- **v0.9.2** (2026-09-04, RELEASED at 0d81c40): *tombstones guard the write path* — the 0.9.0 Tombstone was findable but guarded nothing (active → never `superseded`; sits out the scan → never `in-active-conflict`; duplicate match is same-type; Problem `00cox6i3pj8d`). Now: **`tombstoned` write warning** (role-based, cross-type, carries the tombstone's `note` = why; never blocks); **delete mint carries the buried content** (victim body as `**Removed text:**`, tags, code_refs; pane "Keep the removed text" tick, `keep_text=false` = purge shape) and **rehomes the victim's `about` edges** onto the tombstone (same edge id); **search `tombstone_note`** when a hit carries the role; **`check_claim` `retracted` bucket** (role-sorted before NLI, score in `entailment`; pane group; write-time canon check skips tombstones — one channel per fact); **write-time suspects skip tombstones on both sides** (found by the new MCP test: a bury write paired the tombstone with its victim, inviting a `replaces` that would archive the marker); **the assistant's bury gesture** = add_note Tombstone `Removed: …` + link `replaces` victim (no new tool; 26 stays), taught in instructions + all three skills. Semantics locked: superseded = a successor exists, follow it; tombstoned = killed without one, re-adding is the error. Docs fixed where they implied the mint links its victim.
- **v0.9.1** (2026-09-02): *the pane stops looking foreign, and the docs shoot themselves* — **SelectMenu** replaces all ten native `<select>`s (styled trigger + body-teleported listbox, keyboard nav, flips upward; the native popup looked like another application on Windows, Decision `00cl7d85lj8d`); ontology type card wraps its Durability/Rank-prior row and moves brief **cap/excerpt** onto a row of their own. **Bob lifecycle hooks** (IDE 2.0.2 / BobShell 2.0.1): `setup --cli bob` installs the portable brief script under `.bob/hooks/` and registers it in `.bob/settings.json` — plain-stdout SessionStart, no envelope (unlike Devin), `sh`-prefixed, workspace-relative, 30s timeout; foreign settings get the snippet printed (Decision `00chelyixmxw`). **Screenshot pipeline** (`scripts/screenshots.sh` + `frontend/scripts/shots/`): headless Chromium drives the demo build, manifest per PNG, fresh context per shot, frozen clock + deterministic layouts + motion off = reproducible; 16 shots (9 regenerated, 7 new: node detail, ontology card, custom fields, memory lens, system, history screen, claim check), the standalone/VS Code/JetBrains three stay hand-made; local-only, NEVER CI (mac vs Linux font rasterization). Gotcha: Chromium's scroll-into-view never settles inside the gear menu's capped scrolling body — menu rows are clicked by dispatch (Caution `00cl9kyxmj8d`, Decisions `00cl9kyvmj8d`/`00cl9kywmj8d`). Demo seed caught up with 0.9.0 (custom fields `impact`/`tracker` with values, a Tombstone note, system fixture 0.8.1→0.9.0 — Insight `00cl9kzymj8d`: a feature missing from the demo seed is a feature missing from the docs). Also: `timespec` calendar shifts are checked arithmetic (an absurd month/year count reads as "not a time", never a wrapped instant); the seal key file is created 0600 rather than chmod'd after; **docs sweep** — 13 fixes against code and CLI help (graph.db-as-default, home.db→home.tepin, installer-wires-repos, 8→9 types, agent rosters, SECURITY's shipped CORS allowlist, plugin README binary name; Insight `00cl7d96lj8d`), plus a docs/pane.md section for the session-history screen, which had none.
- **v0.9.0** (2026-08-30): *deletion leaves a trace, fields are yours, rest is sealed* — **Tombstone type role** (9-type default ontology, Retraction in research, new `general` preset; tombstone-role types sit out the conflict scan and never decay; hard delete offers "leave a Tombstone" with reason — and the mint is EXEMPT from required-field enforcement, deletion isn't authoring, Decision `00cfetz4muxp`); **custom fields** (FieldDef in GraphConfig: text/number/bool/date/enum/url, required/applies_to/indexed/show_in_brief; engine-boundary validation with teaching errors naming the roster; reserved-name shadow ban; MERGE patch, null deletes; rename-field = migration; pane sub-menu with built-in-fields reference; indexed values join both search channels); **bitemporal `date_field`** (after/before re-aimed at date-kind fields, from..to = interval overlap, unaimed clock errors); **at-rest encryption** (two switches: graph OFF / history ON default; state in each store's OWN meta `plaintext|sealing|sealed|unsealing`, crash-resumable; `crate::seal` generalizes 0.8.4's HistoryKey verbatim; **`_kw` blind keyword index** — identity tokens plaintext / keyed HMAC sealed, BM25 bit-identical by golden test; history gains its first keyword channel; `POST/GET /encryption` progress; exports stay plaintext; sqlite refuses). **Receipts:** ladder reproduces 0.8.10 to the digit (`0.9.0-ladder-run.log`); posttune FP 0.00@100 / 0.02@1500 — the one honest delta: single-stream BM25 shuffles deep candidates, the weak line re-fits 0.898→0.878 at 1500 (FP 4→7 of 375 controls), top ranks untouched everywhere; canonical protocol `--ladder --posttune --sizes 100,1500` (bare `--posttune` exhausts the 4096-name space at 1500; raw-ladder FP 1.00 is NOT a regression — README's engram row splices the posttune cell, now †-footnoted; Insight `00cfety3muxp`). Also: **Nebula layout removed** (three remain; Tombstone `00cf7rx7iuxp`); **installers stop wiring unasked** (--cli is the opt-in; serve's nudge names the unwired agents with the exact command, Decision `00cffaw0nuxp`); **Windows path escaping** in every config writer/snippet (codex refused its whole config.toml over `\U` — json_str/toml_str, Resolution `00cfetx0muxp`, Caution `00cfety1muxp`); **seam-test sweep** (~20 tests: sealed store × verdicts/suspects/brief/merge/timeline/redaction, keyless placeholder reads, pre-0.9 export+config shapes, handshake unsuccessful branches as pure-fn matrix + 2 e2e journeys; core 232, e2e 8; Resolution `00cfeu05muxp`).
- **v0.8.13** (2026-08-29): *locks release and schemas teach* — **identity-checked engine cache** (issue #8 lock report: `Hub.open` cache hits re-stat the backing file's dev+ino (`StoreIdentity`); a deleted/replaced store is evicted and reopened fresh — tepin-born — instead of served from the orphaned inode; Problem `00cddnieb6xq`); **honest stop** (PID-verified exit — locks release at process exit and /health-silence proved nothing; `/shutdown` → SIGTERM → SIGKILL escalation + port-free check; core exit reordered: bounded 10s engine drain BEFORE `http.abort()`); **version handshake** (`retire_older_core` at serve, bridge bind/rebind, and core start, plus a `bind_or_converge` takeover: an older core is stopped and replaced by the newer binary, a newer one is converged on — never downgrade; a taken port gets 3 health probes before the walk, so a busy core no longer births a split-brain second core); **write tools teach their shapes** (issue #9, Haiku via Devin: `#[schemars(inline)]` on AddNoteArgs/UpdateArgs — batch items were a bare `$ref` hiding every field; vocabulary doc-comments on the two `type` fields; `deny_unknown_fields` on write args — an inline `links` array used to be silently dropped; server `instructions` cut 4.1KB → the contract WITH the 8-type roster and exact call shapes, closing the instructions half of `00c0b7rdbcs4`); **skills show real JSON** (positional pseudo-syntax `link(a, b, answers)` → keyword JSON + an `add_notes`-then-link worked example in all three variants; digest's "batch into add_notes… link as you go" contradiction resolved, near-empty-tree early stop, files-not-directories line; cold-start brief appends `describe_ontology`'s output; AGENTS.md roster gained Anchor + call shapes; aggressive's self-edit footer scoped to the engram repo). Count truth: **26 MCP tools** (0.8.11's "24" was a miscount).
- **v0.8.11** (2026-08-26, RELEASED at f713aa0): *one tool binds and briefs* — **`brief` ABSORBS `set_project`** (24 tools; Decision `00c7ntibghzp`): passing `project` (name/id/absolute path/"home") rebinds the session atomically and returns that project's brief as markdown behind a "Session rebound" line — the issue #4 field report showed the injected brief-first guidance overruling the reporter's set_project-first rule, so the two gestures became one and there is no wrong first call left; resolve-first (a refusal leaves the binding untouched), fallback hint + INSTRUCTIONS + skills + docs all teach the single gesture; SEMANTIC CHANGE accepted: brief(project) no longer read-scopes without rebinding (cross-project peeks = search/list_nodes project args, GET /brief?project=). **Windsurf project wiring** (#7, Decision `00c7nu3fghzp`): `.windsurf/rules/engram.md` always_on rule (critical first line = the brief-rebind; Windsurf has no hooks) + `.windsurf/skills` via the shared install_skills helper. **Devin CLI adapter** (#8, Decision `00c7nucgghzp`): `.devin/mcp_config.local.json` (highest-precedence tier, explicit --db, git-ignored) + `.devin/skills` + SessionStart hook in `.devin/hooks.v1.json` — Devin injects context ONLY via the hookSpecificOutput JSON envelope (plain stdout dropped), so the hook wraps the portable script (awk escaper, test-locked). Release friction: first draft-release dispatch died `startup_failure` before any job (GitHub-transient, workflow unchanged) — the fix is re-dispatch, `gh run rerun` doesn't apply.
- **v0.8.10** (2026-08-23, RELEASED at 732e5b2): *search mixes sessions* — **session-diverse delivery default-on** at `policy.session_diversity_demote` 2 (rank-based at the final cut only, top of a three-seed free zone, inert on the LongMemEval chat register; hits carry `session_id`; Resolution `00c0smup8jlv`); **MCP replies tidied at the ok_json funnel** (ISO instants, null/empty pruned — MCP only, pane/exports raw; Decision `00c0qfxt7jlv`); **delivery-floor bake-off: NEITHER attack ships** (full-note rerank input wins the note register but collapses chat R@5 0.96→0.78; dial-three q25 recall-free ≤500 notes but not 1500 — Problem `00b227i6tdob` stays open pending a chat-register fit; Insight `00c0xcaj9jlv`); eval: `--sessions` bench, `--lme-turns` short-LongMemEval loop, floor rows, README restructured to read historically (baselines re-measured on 0.8.10, replicating 0.8.2 to the digit).
- **v0.8.9** (2026-08-22, RELEASED at afe28a6): *the agent binds itself* — **`set_project`** (25th MCP tool, Decision `00c0b7i9bcs4`): a session rebinds ITSELF to a registered project (name/id/any absolute path inside the root) when its client advertised the roots capability but answered `roots/list` empty (issue #4 field gap: Windsurf, Devin CLI); refusals list the roster, the reply embeds the target's brief, mutable session `Binding` behind one RwLock, hub-level **session census** (touched per tool call, 30-min TTL) under `/system processes.sessions` + pane System panel; brief opens with a set_project hint when a session lands on the home/default-agent rung; skills + docs/runtime.md teach it, one AGENTS.md line automates it. **Every tool description cut to its contract** (Decision `00c0b7rdbcs4`: descriptions are per-session context on EVERY client — verdict duties and safety lines stay, detail moves to arg docs; server `instructions` + response-note strings still uncut). **Registry resolution fix** (Caution `00c0a0697tx7`): `ProjectEntry.db` is wiring, not truth — every reader goes through `resolved_db()` (`.tepin` sibling wins), so cross-project surfaces stop skipping live tepin stores as "db missing". **NLI scoreboard** in Checkup (`GET /conflicts/agreement`): hint-vs-verdict agreement over judged suspects — dogfood graph says 67.5% over 40 hinted pairs, false alarms dominate the errors; read-only, never a calibration input (dial one reads similarity, not the hint). Scope re-cut same day (Decision `00c0lx7phxl0`): session-diverse ranking + delivery-floor work moved to next cycle (bench BOTH floor attacks: dial-three quantile AND wider rerank input), **grep_history ABANDONED** (vector over history suffices; literal grep lives outside engram). Release friction: draft-release runs all four component suites at once and is systematically more starved than a push run — `wait_core_healthy`'s 30s blown once ("core never became healthy", same-commit push run green), rerun cleared it (Caution `00bywotv5tx7`, second symptom).
- **v0.8.8** (2026-08-21, RELEASED): *one heavy core, everything else light* — the machine core (`engram-alpha core`, hidden, spawned detached) owns every store lock, the three models, the pane, and all MCP sessions; `serve` is a converge-or-spawn launcher that registers the repo and EXITS; `mcp` is ALWAYS a light stdio bridge (the direct-open fallback that could turn a session into a second 600 MB store-holder is removed on every backend). Client leases (15s heartbeat, 45s TTL, client name from `initialize`) feed `status`, `/system`, and the pane's Processes census; `stop` is an orchestrated loopback `POST /shutdown` (PID-kill fallback); after 15 idle minutes the core drops all three ONNX sessions (~845→150 MB, lazy reload 0.1–0.5s, `ENGRAM_IDLE_UNLOAD_SECS`, health/status/lease pings exempt from the clock). `--db` is optional: the binding ladder is explicit `--db` → client MCP roots → usable cwd → **default agent project** (pane setting, `~/.engram/settings.json`) → home, rebinding on `roots/list_changed` — which unlocked **Windsurf** (`setup --cli windsurf` writes BOTH global devin configs; survives its JetBrains plugin's launch-from-`/`, roots-silent client). Folder-as-selector everywhere (any path inside a repo resolves the project; `GET /brief?project=`); issues #3–#6 closed; docs/runtime.md + support matrix. Fixed: brief follows the session's binding (`Hub::brief_for` — home-rooted core had every session briefed on the empty home graph), SessionStart hook asks the scoped brief + probes off-PATH binaries, handshake-first bridge (initialize answered immediately; spawn failure errors the first tool call instead of 180s silence — mcp-go kills at ~60s). Field lessons: never `cp -f` over an executed binary on macOS (per-inode kernel signature cache → every exec SIGKILLed while `codesign -v` passes; deploy now rm-before-cp, Caution `00byqnk4w09h`); CI's clippy is newer than local — verify with `cargo +<CI-version> clippy` pre-push; clap doc comments ARE `--help` (paragraph-split summary/detail convention, Insight `00byry1rl7ea`).
- **v0.8.7** (2026-08-15, RELEASED at 19966b5): *search learns time* — ONE temporal grammar (`after`/`before` taking day/ISO/relative phrases the daemon resolves, `during_version` read off the recorded version switches, `order:"chronological"|"recent"`) over BOTH `scope:"memory"` and `scope:"history"`, plus `list_sessions` windowing and `GET /search`; `crates/engram-core/src/timespec.rs` owns it (half-open windows, calendar-correct month/year shifts); the window filters before the reranker and both calibrated cuts, and an unreadable date is an ERROR, never a dropped filter. `order:"recent"` folds history restatements under their newest form (`prior` nesting, gated, cannot lose a hit). **The measured surprise: a time window BUYS recall rather than costing it** — mean R@5 0.743 → 0.943 and *oblique* 0.263 → 0.830 on 2100 notes, unanimous across three seeds (`--window` bench, Insight `00bn955lztib`); `policy.window_overfetch` 8 → 2 as a result (depth past 2 is dead weight; the 1→2 step is soft — seed 3 dissents at 180 days). That bench found a shipped-same-day bug: **sqlite-vec REFUSES k > 4096** and `search_vec` quadruples k internally, so any `limit >= 11` beside a window errored and an error empties the search — indistinguishable from the "graph is silent" verdict (Caution `00bn94lkztib`; harnesses must PANIC on retrieval errors, never score them zero). Also: redaction judges entropy **per separator-delimited segment** (model slugs/target triples/URLs survive, structureless secrets still die; named patterns untouched; the 15 already-damaged nodes stay — mechanism, not past), SECURITY.md spells out graph = redacted-not-encrypted vs history = redacted-AND-encrypted; fs-notify pulls the next harvest forward while the 60s sweep stays the guarantee (every watcher failure degrades to the old behaviour); skill teaches multi-query reformulation on a weak/none verdict; hits carry `created_at`.
- **v0.8.6** (2026-08-13, RELEASED at 72618e5): *the 2026.1 rescue* — issue #1 fixed by **dual JetBrains artifacts** (`X.Y.Z-261` since 261/until 261.* WITHOUT the `intellij.platform.ui.jcef` module dep, `X.Y.Z` since 262 WITH it; `-PplatformLine` picks the line, `processResources` strips the dep with platformLine as a task input, CI builds/verifies/signs/publishes both, `runIde -PsplitMode=false` is what reproduces the classic loader that split mode hid); **update awareness** (doctor always checks GitHub releases, serve notifies at most once per 24h via `~/.engram/update-check.json`, `ENGRAM_UPDATE_CHECK=0` off, never auto-installs); pane bare-minimum chrome breakpoint 400px → 500px. Release note: nine assets, the first release with two signed plugin zips (`publishPlugin` runs twice — the second re-plans because `platformLine` changed).
- **v0.8.5** (2026-08-13, RELEASED): *the first field reports* — tepin lock safety (`mcp` never direct-opens a tepin store; the direct hub's factory refuses tepin satellites so a bridge can't grab home.tepin; spawn survives a missing `.engram/`; 180s first-run wait; doctor treats core-held stores as owned, not locked — found via Bob IDE holding MedMentor's graph + home.tepin hostage); MCP troubleshooting (#2: bridge reqwest client opts out of proxies — corporate proxy intercepted loopback; `.engram/mcp.log` tees what IDE clients swallow, `ENGRAM_MCP_LOG=0` off; doctor proxy-env warning; docs section); setup/doctor config self-consistency (setup wrote `graph.db` while the store is `graph.tepin` and doctor flagged its own config — setup now writes the resolved path, doctor compares the store a path OPENS). Field lesson: two installed binaries (`~/.local/bin` via installer vs `~/.cargo/bin` via deploy) run different versions silently.
- **v0.8.4** (2026-08-12, RELEASED at d59c3b5): *the history layer* — sealed session recording (sibling `history.tepin`, zstd→XChaCha20, keystore key, OPT-IN), sweep harvester + seven roster adapters (Bob = one SQLite for IDE+Shell, timestamp cursor), born-in provenance both ways (get_node `born_in`, expand_history `notes`, `list_sessions`), sectioned search behind the calibrated verdict (cascade receipts), pane history view (lanes/zigzag, session-chip links, narrow-adaptive), `setup --cli bob`. Release lessons: cargo fmt BEFORE the release commit; keyring's Linux backend links system libdbus (installed in backend+release workflows, documented for source builds); CI path filters mean .github/docs-only commits trigger no component runs.
- **v0.8.3** (2026-08-10, RELEASED): *batch width was the memory* — inference batch capped at 2 (`engram_core::onnx`, was fastembed's 256), which cut the daemon's runtime growth to near nothing AND cut eval wall-clock ~40% (BatchLongest padding waste); headline metrics identical on all seven arms at sizes 100+500, only float-summation noise moves. Three suspects measured and REFUTED: ORT arena, per-session thread pools, malloc free-list retention. `scripts/mem-probe.sh` is the harness. Knobs: `ENGRAM_ONNX_BATCH` / `_THREADS` / `_ARENA`. Also *default embedder pinned to fp32* (`onnx/model.onnx`, explicit like the reranker) — the shipped weights now match the ones every `eval/results/` receipt was measured on; int8 stays a ~100 MB option behind a `--ladder` run, and pre-existing int8 provisions are NOT replaced (`provision()` skips a dir that already has a model.onnx).
- **v0.8.2** (2026-08-09, RELEASED): *merge_nodes* (atomic consolidation, edges rehome, victims archived behind `replaces`); *LongMemEval* — the first corpus we didn't generate (SHA-pinned, as-is ingestion, retrieval-graded, chat ontology as data, ollama/GPU embedder for the harness only); *supersession-chain bench* (`--chains`); corpus vocabulary enrichment (12→25 per slot pool — numbers before/after not comparable); budget sweep (floor/pool levers refuted again).
- **v0.8.1** (2026-08-04, RELEASED — the pane cycle that opened as 0.8.1 folded in): *knee trim* (TAA-k, `knee_cliff`), *phantom-probe weak line* (auto-tune dial two, graph-vocabulary probes, floor-relative clamp), *"likely not in memory" recommendation verdict* (never cuts), `--posttune` end-to-end mode, pre/post-tune rows in eval README; *tasksource NLI swap* (deberta-v3-small-tasksource-nli default, co-reference false contradictions fixed, own HF ONNX export, MobileBERT stays selectable). Field lesson: *register-dependent score scales* — absolute thresholds don't transfer between graphs, relative mechanisms do.
- **v0.8.0** (2026-08-03, RELEASED): *measured not promised* — attention metrics (focus/noise/FP), gradation ladder, floor sweep; *calibrated delivery* (`delivery_floor`, strong/weak/none verdict); *auto-tune* dial one (conflict floor from judged history).
- **v0.7.3** (2026-07-28): *retired means retired* — supersession retires from any edge path; archived hidden by default; per-graph pane state; cold-start + preset picker.
- **v0.7.2** (2026-07-27): *eval harness born* (invented-subject corpus, arms, ladder); search retune (keyword 0.15 + reranker VOTES); mobilebert NLI swap; check_claim confidence gate; real-graph suspect eval.
- **v0.7.1** (2026-07-25): *timeline release* — feed view + lenses, graph↔feed sync, control kit, `set_version` auto-enable, CHANGELOG convention born.
- **v0.7.0** (2026-07-23): *customization* — per-graph GraphConfig (ontology/policy/brief), redactor UI + presets, generated skills, version tracking, handoff tag, file-read match hook, session-boundary validation, tepin auto-migrate.
- **v0.6.x** (2026-07-20..22): *Store trait + TepinDB cutover*, model selection + hot-swap, MCP streamable-HTTP transport, machine hub + convergent serve + per-project MCP, multi-project federation + home graph, conflict push, claim search, CORS allowlist, docs/ split.
- **v0.5.x** (2026-07-13): *local cortex* — reranker precision layer, NLI logic layer + co-reference caveat, Checkup panel, digest skill.
- **v0.4.x** (2026-07-11/12): *rename to engram-alpha*, doctor, bulk MCP tools, full-field retrieval index, **trust v2** (time/exposure don't validate; confirmed_at; pin; demotion via judged conflicts), write-verdict protocol.
- **v0.3.0** (2026-07-10): plugin + marketplace, audit journal, session-brief hook, drift scan, timeline, four layouts, skill overhaul.
- **Phase 0–1** (2026-07-02..06): core graph + hybrid RAG + pane CRUD, conflict scan + suspects, decay pass, brief.

## Now / next (keywords)
**v0.9.2 released 2026-09-04** at 0d81c40 (all five Release jobs green, nine assets; graph working version 0.9.2 — opened at cycle start this time). Owed: `scripts/deploy-pane.sh` + `/mcp` reconnect so live sessions get the `tombstoned` warning; CI annotations say the Node 20 actions (checkout@v4, setup-node@v4, upload-artifact@v4, publish-vscode-extension@v2) are being forced onto Node 24 — bump before GitHub drops Node 20. v0.9.1 released 2026-09-02 (the polish cycle on top of 0.9.0's tombstones + custom fields + encryption — see Chronicle). Documentation screenshots are regenerated by `scripts/screenshots.sh` (local-only, never CI) whenever the pane changes shape, and the Pages demo is the studio: a user-visible surface missing from `frontend/demo/data/` is missing from the docs too. History-channel chat-register pricing deferred with LongMemEval to a future cycle; whether the 0.9.0 FP 0.02@1500 changes the README headline row is a re-baseline-at-next-measure question, not a one-cell edit. Machine core on 8787 — the version handshake retires older cores automatically after a deploy, but live stdio sessions still need `/mcp` reconnect. **0.8.13** answered the issue #8 lock report (identity-checked engine cache Problem `00cddnieb6xq`, honest PID-verified stop, version handshake) and issue #9 (schema/skill graspability, Problem `00cddntfb6xq`). Issues #4/#7 fixed in 0.8.11–0.8.12, #8/#9 in 0.8.13, all open until the reporter confirms (replies to the reporter = user action); issue #1 (JetBrains 2026.1.x) fixed in 0.8.6, open until the reporter confirms the `-261` artifact. Delivery-floor Problem `00b227i6tdob` stays open pending a chat-register fit (0.8.10 bake-off: neither attack shipped). `grep_history` is ABANDONED for now (don't resurrect without a field case vector search demonstrably whiffs). Unscheduled: the **LongMemEval record attempt** — Intent `00bht8iluk1h` (online half: own API feeder + Claude Code arm, GPT-4o judge, survey published runs first; switch the arm to ingest through the real history layer), history phase-2 tail Intent `00bhzbg0itqk` (episode segmentation measure-first, thinking blocks, zstd dictionary, sessions-as-timeline-blocks, retention knob), Windsurf history adapter (blocked: Cascade transcripts encrypted at rest), Developer ID signing of releases (kills both the keychain prompts and the signature-cache class). Other open threads: MCP response-note strings still uncut (last of `00c0b7rdbcs4` — `instructions` cut in 0.8.13), *Provence-class sentence pruning*, *residual oblique misses*, session quarantine, downstream-use confirmation, SHA-256 model pinning, Cursor wiring, plugin-directory publishing (user action) — the curated-store sealing decision CLOSED in 0.9.0 (the graph switch exists, default off). Windsurf support is in-tree and field-testing (default agent project is its binding rung); Kilo adapter remains fixture-only (unverified live); BobShell ingestion assumed shared-store (verify when its login works). Watch in CI: `serve_http_only_blocks_while_core_lives_and_exits_when_it_dies` flaked twice under local parallel load. **E2e suites** live in `crates/engram-cli/tests/{e2e,e2e_wiring,e2e_encryption}.rs` (shared harness `e2e_common/`, ~40s local): lifecycle journeys (issue-#8 wipe, PID-verified stop, update takeover both directions via `ENGRAM_TEST_VERSION` — one binary plays two versions, bridge-driven core replacement, serve/stop churn + concurrent-serve race) and wiring (setup output carries current-generation skills, the Devin envelope hook delivers a brief on a fresh repo, the written MCP config launches a bridge serving 26 tools with no $refs); they ride the normal backend `cargo test --workspace`.
