v0.5.5
The audit release — security & correctness fixes from a full technical audit
(docs/IMPROVEMENT-PLAN.md), no behaviour changes for the happy path.
Fixed
- Lexical search now works for non-Latin text (Cyrillic, Greek, CJK …). The
query tokenizer was ASCII-only while the FTS index usedunicode61, so e.g. a
Russian query matched nothing in lexical mode. Also splitssnake_case. - Engine writes are transactional — an exception mid-write no longer leaves an
open transaction that the next request silently commits (which produced memories
invisible to lexical search). Row + FTS commit or roll back together. - Malformed client input returns a JSON 400 instead of a traceback and a dropped
connection (limit="abc",importance:"high", …). - Editing a memory refreshes its
content_hash— a stale hash corrupted dedup
both ways. ygg doctorno longer prints "All good." with no MCP registration anywhere.
Security
- No
yggdrasil-demo-tokenfallback in the engine — a bareygg servereuses or
generates the 0600~/.yggdrasil/tokeninstead of a publicly-known constant. - The Streamable-HTTP MCP facade refuses to start without a token (
YGG_MCP_INSECURE=1
opts into open mode for local testing). ygg_materializeoutput confined to the vault root — a remote MCP client could
previously write attacker-seeded.mdanywhere the user can write.- Auth token no longer written in plaintext into launchd plists, MCP registrations,
or~/.claude.json— everything resolves the 0600 token file at call time. - Timing-safe token comparison (
hmac.compare_digest) + a Host-header check on
loopback binds (blocks DNS-rebinding drive-bys).
Changed
- Untracked the
.mcpbdesktop bundles (hosted on GitHub Releases); ignore
.cache/,.claude/,scratchpad/.