Skip to content

Synapse v1.9.1 — "fast paths"

Second release of the v2.0 train. Theme: backend query/index performance, ingest-tail write coalescing, a cross-vault citation-leak fix, automated backups and supply-chain hardening, and non-convergence diagnostics for a bug reported live during 1.9.0's rollout. Five workstreams, three serialized Alembic migrations (0033 → 0034 → 0035).

Fixed

  • Lint's broken-wikilink scan re-ran a full resolver-map build and event-loop-blocking fuzzy matching per dangling link. Resolver maps now build once per scan; the fuzzy-suggestion loop runs in asyncio.to_thread.
  • UUID-column casts in retrieval/graph queries defeated the primary-key index — CAST(id AS TEXT) = :param forced a sequential scan. Casting the bind parameter to uuid instead restores index use: measured ~650× faster on _load_page_meta and ~330× on _expand_frontier.
  • reresolve_dangling_links resolved dangling links from every vault against the active vault's map — a correctness bug. Now scoped to the requesting vault, backed by a new partial index (migration 0033).
  • ingest_runs had no index at all — new composite vault_id, started_at index (migration 0034).
  • The per-page ingest tail did 2 full table scans and rewrote index.md after every single generated page. Resolver maps now build once per document; index.md and data_version update once per document instead of once per page.
  • A cross-vault citation leak in retrieval. Qdrant points carried no vault_id, so Phase-1 vector search queried across all vaults unfiltered. Points now carry vault_id (with a payload index). A backfill script is provided for pre-existing points.
  • "Non convergito" gave no indication of why. The run detail view now shows the actual stop reason, iteration count, last validation errors, and token budget spent vs. cap (new ingest_runs.diagnostics column, migration 0035).
  • GraphCache's HIT path paid 3 queries and a full Pydantic re-serialization on every request even when nothing changed — now caches pre-computed totals and the serialized body.
  • GraphCache's debounce had no maximum wait — a continuous ingest burst could defer the background FA2 recompute indefinitely. Added a debounce max-wait plus a stale-while-revalidate path.

Added

  • Automated Postgres backups. A new backup operation in the existing OpsScheduler (off/hourly/daily/weekly) runs pg_dump -Fc with retention pruning; POST /ops/system-update now dumps before poking Watchtower.
  • Supply-chain hardening: backend/requirements-lock.txt / requirements-prod-lock.txt via uv pip compile; a Dockerfile production target; .github/dependabot.yml (weekly pip/npm/actions).
  • A workflow_dispatch-only live-smoke lane (live-smoke.yml): runs pytest -m live plus the ADR-0083 parity harness against a manually-supplied llm_wiki gold snapshot.

Upgrade

Run Alembic migrations 0033, 0034, 0035 in order. Run the Qdrant backfill script for pre-existing points:

python scripts/backfill_qdrant_vault_id.py