Skip to content

Synapse v1.9.2 — "real boundaries"

Third release of the v2.0 train. Theme: finishing the module decomposition the 1.7.0 sprint started, behind compatibility facades — pure refactors, zero observable behavior change. Seven workstreams, zero migrations (deliberately: this release moves code, not schema).

Changed

  • app/runtime_state.py extracted from main.py. MCP source classification, PBKDF2 token helpers, the four DB-backed config caches, and the bearer-auth middleware now live in one module with typed accessors. The 13 duplicated _LazyMain proxy classes across routers are gone. Temporary app.main.* aliases remain for this release (dropped in 2.0.0).
  • routers/config.py (2,800 lines) split into a package by domain: provider config, provider-vendor probes, embedding, MCP, import-schedule, clip, web-search, CLI-auth, app-config — plus app/schemas/config.py for the shared DTOs. OpenAPI is byte-identical before/after.
  • ops/review.py (3,960 lines) split into a package: queue.py, propose.py, create.py, suggestions.py, prompts.py.
  • ops/lint.py (2,666 lines) split into a package: detectors.py, fixes.py, semantic.py, persistence.py.
  • Domain exception taxonomy (app/errors.py): a SynapseError hierarchy (NotFound, Conflict, Validation, Upstream, and 9 others) with one global FastAPI handler. The standardized error envelope itself is deferred to 2.0.0; this release only lands the infrastructure plus a representative migration slice.
  • Frontend: a shared createPollChain/usePollChain abstraction replacing 9 independent hand-rolled poll implementations; api/errors.ts extracted from graphClient.ts; api/types.ts (~1,100 lines) split into one file per domain; a new appStore split out of graphStore; ReviewQueueView.tsx (2,149 → 868 lines) had its inline subcomponents extracted.
  • Import-linter layering enforcement (.importlinter config in pyproject.toml, wired into CI as a blocking lint step): four contracts encode the layer boundaries.

Upgrade

No Alembic migrations. Pull new images.