v2.1.1 — MCP git sync, audit hardening, iOS PWA download fix
Merges development into main, covering everything since the last release on main (v2.0.0). This spans two version bumps — v2.1.0 (MCP git sync) and v2.1.1 (audit hardening + iOS PWA download fix) — 26 commits, 66 files (+6611/−509).
v2.1.1 — Audit hardening & iOS fix
Security, performance, and operational hardening from the 2026-06-11 codebase audit (audit-report.md), plus an iOS PWA download fix.
Fixed
- iOS PWA markdown downloads arrived as HTML. iOS ignores the
<a download>attribute in standalone mode and treats the click as a navigation; Workbox's SPA navigation fallback then served the cachedindex.htmlfor/api/note/<slug>/download. Added anavigateFallbackDenylistfor/api/*,/vault-assets/*, and/healthso those navigations reach the network. (Verified fixed on-device.)
Security
- Optional web API authentication via
HATCHDOOR_WEB_BEARER_TOKEN: all/api/*,/vault-assets/*, and downloads require the token (Authorization: Bearerheader oraccess_tokenquery param); the PWA prompts on 401. (F-01) - Default bind host changed to
127.0.0.1;0.0.0.0is now explicit opt-in. (F-01) - Coalesced concurrent
/api/refreshrequests to prevent overlapping full reindexes. (F-02) - Constant-time comparison for MCP and web bearer tokens. (F-06)
- SVG vault assets served with
Content-Security-Policy: sandbox+Content-Disposition: attachment. (F-09) - Stopped leaking absolute paths / raw internal errors in HTTP error bodies. (F-10)
- Capped
POST /api/resolve-batchat 200 targets. (F-11)
Performance
- Moved reindexing, embedding, and query embedding off the async runtime via
spawn_blocking, holding the cache write lock only for the final swap. (F-03) - MCP write tools resolve the target note from the SQLite cache instead of rebuilding the full vault index from disk per write. (F-04)
- Enabled SQLite WAL mode + a pooled set of read connections for parallel reads. (F-05)
Correctness & operations
- Validate
McpConfigonce at startup (fail fast when write mode lacks a bearer token). (F-07) - Git sync refuses to force-checkout over uncommitted manual edits to tracked vault files. (F-08)
- Hard-coded
90-archive/prefix moved toHATCHDOOR_ARCHIVE_PREFIX. (F-12) - Added a Forgejo Actions CI workflow (backend fmt/clippy/test; frontend lint/typecheck/test/build) and a Compose
healthcheck. (F-13) - SSE vault-events stream emits current revision on broadcast lag so slow clients resync. (F-16)
/healthrunsSELECT 1against the cache; binary gained--healthcheckmode for the container probe. (F-17)
v2.1.0 — MCP git sync
Added
- Optional automatic git sync of the vault: successful MCP write tools commit and push to the configured remote with debounced batching, conflict-abort semantics, and an immediate startup flush of stranded commits.
get_git_sync_statusMCP tool and a git-sync warning on write-tool responses.edit_noteandreplace_sectionMCP write tools.
Changed
- Richer git sync status reporting with plural-aware commit messages.
- Pinned the Rust toolchain to 1.96.0 and reformatted the tree.
Fixed
- Enabled the git2
httpsfeature for TLS remote transport. - Vault watcher ignores
.git/so sync churn does not trigger reindexing.
Test plan
-
cargo test(backend) andnpm test(frontend) pass — enforced by the new CI workflow - Built
v2.1.1image and deployed to batterbrain;/healthreturns 200 - iOS PWA markdown download now returns the
.mdfile (no longer HTML)