Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ADR-038: Ship v1.0 on ort 2.0.0-rc.12 with a tracked exit

Date: 2026-06-20 Status: Accepted Author: Rômulo Febasi

Scopes SYN-276 (#264). Companion to ADR-008 (embeddings/NER backend). The v1.0 milestone freezes the Synapse surface (schema / CLI / MCP); this ADR states what that “stable” claim does and does not cover for the transitive on-device inference stack.


Context

Synapse’s on-device embedding + NER runs on ONNX Runtime via the ort crate, pinned to =2.0.0-rc.12 (a release candidate). This pin is transitive and forced, not a free choice (Cargo.toml §inference, lines ~186-189):

  • fastembed 5.15 (the embedding backend) pins ort = "=2.0.0-rc.12" exactly.
  • canonical gline-rs (the NER crate) pins ort = "=2.0.0-rc.9", which conflicts; the kreuzberg-gliner-rs fork re-pins to rc.12 to align.

So the whole inference stack sits on rc.12, and ort cannot be moved to a final release until both fastembed and the NER fork move first: Synapse cannot unilaterally bump it. The stack is built, tested, and working on rc.12 (373 lib tests green; cargo deny check clean: no advisory blocks it).

Tagging a release branded “stable” (v1.0) on an RC dependency is a real maturity question that should be decided explicitly rather than left as an undocumented pin.

Decision

Ship v1.0 on ort = 2.0.0-rc.12 (Option A), with a tracked exit.

  • The v1.0 “stable” promise covers the Synapse public surface: the Markdown/frontmatter schema, the CLI, and the MCP tool surface: under semver (BR-11.2). It does not assert that the transitive ONNX Runtime is a final release; that is a documented caveat, not a broken promise.
  • The exit criterion: when fastembed (and kreuzberg-gliner-rs) publish versions depending on ort 2.0.0 final, adopt it in a 1.0.x patch: bump the three together, run cargo build --release --all-features && cargo test --all-features && cargo deny check, re-run synapse-bench to confirm no embedding/NER regression, and ship. Until then, no action (the pin cannot move).
  • Do not bump Cargo.toml/Cargo.lock speculatively: a partial bump that desyncs fastembed and the NER fork breaks the build.

Consequences

  • Improves: an honest, written posture instead of a silent RC pin; the “stable” claim is correctly scoped to the surface semver actually governs; no premature dependency churn on the inference path.
  • Worsens / limits: v1.0 ships with an RC ONNX Runtime. If ort 2.0.0 final differs from rc.12 in a way that changes embedding/NER behavior, a 1.0.x patch is needed once upstream supports it, but the semantic models download on consent and the index is disposable, so any behavior change is reproducible and re-derivable (syn embed --all / syn reindex), never silent data loss.
  • Open: the bump is gated on upstream (fastembed + the NER fork adopting ort 2.0.0 final). Track it with the dependency-health cadence; this ADR is the exit criterion of record.

Alternatives considered

  • Option B: wait for ort 2.0.0 final before tagging v1.0. Rejected for now: adoption is not in Synapse’s hands (it requires fastembed + the NER fork to move first), and blocking the v1.0 tag on an upstream release with no committed date would hold the whole milestone hostage to a transitive pin. Revisit only if upstream ships final and the bump tests clean on all targets.
  • Swap the inference stack to a final-release ONNX binding now. Rejected: the backend choice (fastembed + BGE-M3 + GLiNER via the fork) is settled by ADR-008; replacing it to dodge an RC is a far larger, riskier change than the RC itself warrants for a single-user local-first tool.
  • Pretend the RC is irrelevant and say nothing. Rejected; that is exactly the undocumented-pin the “never fake green / honesty” discipline forbids; a “stable” release should state what its stability covers.