Engram v1.16.0 lands a broad, high-impact wave of fixes and features: opt-in HTTP auth and constant-time token comparisons, new CLI delete sub-commands, a TUI clipboard shortcut, cross-project personal search, case-insensitive legacy project matching, a cloud allowlist wildcard, Pi setup hardening, and a wholesale docs refresh. Multiple external contributors and issue reporters drove this release.
Highlights
Security
- Optional local auth for destructive HTTP endpoints (
ENGRAM_HTTP_TOKEN): when set,DELETE /sessions/{id},DELETE /observations/{id},DELETE /prompts/{id},GET /export,POST /import, andPOST /projects/migraterequireAuthorization: Bearer <token>. Unset = open (zero-config preserved). Constant-time compare viahmac.Equal. - Constant-time token comparisons: bearer and admin token checks in
internal/cloud/authandcloudserverusehmac.Equalinstead of==/!=, eliminating the timing-oracle. - Obsidian exporter path traversal:
internal/obsidian/exporter.gosanitizes project and type components beforefilepath.Joinand adds a post-join containment check, rejecting any path that escapes the export root.
CLI
engram deletenow supports sub-commands:delete observation <id>,delete session <id>,delete prompt <id>, anddelete project <name>. All accept--hard. The legacyengram delete <obs_id>form still works.store.DeleteProjectatomic cascade: orphansmemory_relations, removes observations (soft or hard), prompts, and sessions (hard only — the FK constraint blocks session removal while soft-deleted observations still reference them).
TUI
ckeybinding copies the highlighted observation to the clipboard via OSC 52 on Recent Observations, Search Results, Observation Detail, and Session Detail. Works over SSH, no system deps.
Search and scopes
mem_searchacceptsall_projects: trueto search every project at once instead of the resolved one.scope=personalwithout an explicit project now searches personal observations across all projects (mem_search,mem_context).globalis a valid scope alongsideprojectandpersonal(was silently coerced toproject).- Legacy mixed-case project data is now searchable: store queries use
LOWER(project) = ?so observations stored asEbook2Audioare found when queried asebook2audio— the MCP path normalizes; the CLI was the only path that happened to work before. - Configurable timestamp display:
ENGRAM_TIMEZONEsets the display timezone for the TUI and the cloud dashboard. Falls back to system local; UTC is preserved in storage.
Cloud
ENGRAM_CLOUD_ALLOWED_PROJECTSaccepts*to allow every project (per-project enforcement bypassed). Useful for dev and internal deploys.sync --cloudsends the Authorization header when onlycloud.jsoncarries the token:resolveCloudRuntimeConfigno longer zeroes the file token before reading the env var.cloud statusdetects a dead local daemon with a 1-second probe and prints actionable guidance; the launchd unit template is documented.
MCP
handleSessionSummaryhardened: it now respects the process-level project override (ENGRAM_PROJECT/engram mcp --project) consistent with every other write tool, and rejects empty or whitespace-only content beforeAddObservation. This fixes stucksync_mutationrows that blockedcloud upgrade.
Windows
CLAUDE_PLUGIN_ROOTis escape-quoted in everyhooks.jsoncommand entry, so all Claude Code hooks fire on profile paths containing spaces (e.g.C:\Users\John Doe\...).
Pi
engram setup pipinsnpmCommandto a mise-stable form (["mise","exec","node@X.Y.Z","--","npm"]) when mise is detected and no command is configured, preventing duplicate installs when Node drifts. Existing values are preserved.- Pi status bar maps
ambiguous_projectto an actionable label instead of the genericerror.
Docs
- Wholesale sync: the
DOCS.mdenvironment-variables table went from 3 to 17 rows;printUsage()env block synced with code; CLI reference tables inREADME.mdanddocs/ARCHITECTURE.mdnow includedoctor,conflicts,delete, andprojects prune; Codex troubleshooting for "MCP Transport closed" was added; the newENGRAM_HTTP_TOKEN,ENGRAM_TIMEZONE,scope=personalcross-project behavior,globalscope,*cloud wildcard, and PinpmCommandpinning are all documented.
Contribution highlights
Thanks to the external contributors and issue reporters who shaped this release:
- @carlosmoradev shipped #408 (
all_projectsflag formem_search), #346 (configurable timezone), and #410 (install-from-source version-stamp docs). - @jlsevillano shipped #337 (dead-daemon detection in
cloud statusand launchd documentation). - Issue reports that drove targeted fixes: #180 (Obsidian path traversal), #200 (HTTP auth), #350 (constant-time compare), #260 (cloud wildcard), #146 (MCP search empty for legacy data), #391 (personal-scope filter), #403, #413, #393 (
handleSessionSummarygaps), #122 (globalscope), #343 (sync --cloudauth header), #209, #218, #219 (CLI delete), #141 (TUI copy), #420 (Windows hooks quoting), #385 (PinpmCommand), #384 (Pi status bar), #167 (Codex docs).
Pi companion notes
No new gentle-engram npm package was published in this release. The current Pi companion remains gentle-engram@0.1.7; this release updates the main Engram binary, the Pi setup logic in engram setup pi, and the Pi documentation.
Changelog
- #443
docs(codex): add troubleshooting for MCP Transport closed error(closes #167) - #442
fix(plugin): quote CLAUDE_PLUGIN_ROOT in hooks for paths with spaces(closes #420) - #441
feat(store,cli): cascade DeleteProject + engram delete session|prompt|project(closes #218, #219) - #439
fix(pi): show actionable status for ambiguous project errors(closes #384) - #436
docs: bring docs up to date with recently merged features(closes #435) - #434
feat(cli): add engram delete command to remove observations(closes #209) - #433
feat(tui): add clipboard copy keybinding via OSC 52(closes #141) - #432
fix(pi): pin npmCommand to stable mise node spec(closes #385) - #431
feat(cloud): wildcard support for ENGRAM_CLOUD_ALLOWED_PROJECTS(closes #260) - #430
fix(cloud): fall back to cloud.json token when ENGRAM_CLOUD_TOKEN is unset(closes #343) - #429
security(server): add optional local auth for destructive HTTP endpoints(closes #200) - #428
fix(store): handle global scope in normalizeScope(closes #122) - #427
fix(store): use case-insensitive project filter for legacy mixed-case data(closes #146) - #426
fix(security): replace timing-unsafe token comparisons with hmac.Equal(closes #350) - #425
fix(mcp): skip project filter for scope=personal with no explicit project(closes #391) - #424
fix(mcp): harden handleSessionSummary process override and empty-content guard(closes #403, #413, #393) - #423
fix(obsidian): prevent path traversal in exporter file path construction(closes #180) - #410
docs: clarify version stamp PATH gotcha and Claude Code schema error(closes #67) - #408
feat(mcp): add all_projects flag to mem_search(closes #303) - #346
feat(timeutil): support configurable timezone for timestamp display(closes #169) - #337
feat(cloud): detect dead local daemon in cloud status and document launchd unit(closes #279)