Skip to content

Synapse v1.9.0 — "clean room"

First release of the v2.0 train (1.9.x → 2.0.0, plan set 2026-07-16 from an 8-dimension multi-agent audit of 1.8.1). Theme: repo hygiene, test infrastructure, and security hardening — no user-facing feature work; every change is behavior-preserving or additive/opt-in. Ships in five workstreams.

Fixed

  • Backend watcher could drop an in-flight ingest task to garbage collection. watcher.py's file-change handler fired asyncio.create_task without retaining a strong reference. It now holds one via the shared _bg_tasks set.
  • Stats caches (/stats/overview, /stats/sections, /stats/groups) were not vault-aware. Cache keys now include vault_id.
  • A misleading AC-K6-2/3 warning fired on every raw source file. The K6 frontmatter check only applies to generated wiki/ pages; the warning is now wiki/-path-only.
  • overview.md/index.md/log.md were invisible in the Nav Tree right after creating a new vault. POST /projects now explicitly indexes the three scaffolded files right after bootstrap.
  • A CTA on the Home dashboard was silently broken in dark mode. The "review only" button used the class syn-button--ghost, which exists in no stylesheet. Fixed to syn-btn--ghost.
  • Three prominent Home dashboard cards showed Italian text in the English locale. home.systemStatus.title, home.groups.title, and home.activeJobs.title held their Italian source strings. Retranslated; a new i18n-language-leak.test.ts CI gate catches the class going forward.
  • A dozen aria-label/toast strings were hardcoded in English. All routed through t().
  • Keyboard shortcuts (⌘1–5) and the command palette had drifted from the 1.7 nav rail. Both realigned to the current rail order.
  • ConfirmDialog did not restore keyboard focus on close, and one native window.confirm was still in use. Both fixed.
  • Marker and Whisper were reachable from the whole LAN with no authentication, while the backend itself was already loopback-bound. Both now bind to ${SYNAPSE_BIND_HOST:-127.0.0.1}.

Added

  • provider_config.base_url allowlist validation (write-time only): scheme must be http/https; host must be localhost, 127.0.0.1, host.docker.internal, an RFC1918 private address, or a known provider host.
  • Rate limiting on authentication failures. Repeated 401 responses from one client IP now trip the existing rate-limit infrastructure (429 after the configured threshold).
  • Optional QDRANT_API_KEY support for Qdrant deployments that require authentication.
  • Shared LLM-call helper (app/ops/_llm.py). Seven ops modules consolidated into one typed helper; 446 duplicated lines removed.
  • Shared SQLite test fixture. 52 hand-written CREATE TABLE statements across 14 test files replaced with one Base.metadata.create_all()-based fixture.
  • CI hygiene: a junk-file guard; an Alembic single-head check; ci.yml/desktop-release.yml concurrency groups; Playwright now retries once in CI only.
  • ADR corpus unification: retired the legacy ADR-NNNN-*.md naming (32 files renamed, 76 inbound links rewritten). New scripts/check_adr_index.py wired into the Docs Gate.

Upgrade

No Alembic migrations. Pull new images. If you have Marker or Whisper exposed on 0.0.0.0, review your SYNAPSE_BIND_HOST setting (defaults to 127.0.0.1).