8.5 KiB
07 — Research Findings (Stack Validation)
This document records the technical feasibility checks performed before committing to a stack. Each finding includes the conclusion that fed into the ADRs. Dates reflect research done June 2026; re-verify versions at implementation time.
Summary
Every load-bearing assumption in the design document is supported by a mature, offline-capable,
permissively licensed component. No blocker was found. The one area needing care is the NPU
path (newer, vendor-dependent) and .pst parsing (use a battle-tested library, treat as
read-only). Both have viable primary + fallback options.
Findings
App shell — Tauri 2 ✅
Tauri 2.0 reached stable in October 2024 and is the current major line. On Windows it renders through WebView2 (the OS Chromium-based webview) rather than bundling a browser, which is the key reason its binaries and memory footprint are far smaller than Electron's — directly serving WA's "fast, low memory" goal. Cross-platform (Windows/macOS/Linux) leaves the door open for the design doc's "future" non-Windows support without a rewrite. → ADR-0001.
Frontend — Svelte ✅
Svelte compiles components to small imperative JS with no runtime framework shipped, giving the smallest bundle and lowest per-view memory among mainstream options — consistent with the low-overhead NFRs. Pairs cleanly with Tauri via Vite. → ADR-0002.
Audio capture — WASAPI loopback in Rust ✅
The wasapi crate provides safe Rust access to WASAPI including a loopback example
(capture system output without a meeting bot). cpal is the cross-platform fallback.
Correction (Phase 1 implementation, verified against wasapi v0.15 source and current
Windows): AUDCLNT_STREAMFLAGS_LOOPBACK and AUDCLNT_STREAMFLAGS_EVENTCALLBACK can be
combined — the crate wires both flags together for a render-device-opened-as-capture client, and
the capture loop waits on the WASAPI event handle (with a short timeout so it can also notice a
stop/pause request) rather than busy-polling. The pre-implementation note below describing a
polling-only design was inaccurate; docs/02-architecture.md's "Audio thread" section has been
corrected to match.
Transcription — whisper-rs (+ ONNX for NPU) ✅
whisper-rs wraps whisper.cpp with feature-gated acceleration: CUDA (NVIDIA),
Vulkan (cross-vendor GPU incl. AMD/Intel), ROCm/hipBLAS, Metal, OpenBLAS, and
plain CPU. whisper.cpp has no native NPU backend, so the NPU tier is served separately via
ONNX Runtime (see below) running a Whisper-ONNX model. This split — whisper.cpp for
CPU/GPU, ONNX for NPU — is the basis of the acceleration ladder. → ADR-0003.
Hardware acceleration — ONNX Runtime ort + DirectML/Windows ML ✅
The Rust ort crate exposes ONNX Runtime execution providers including DirectML, which can
target an NPU (device_filter = "npu") on Windows. Execution providers fall back in order
(NPU → GPU → CPU) automatically when an operator is unsupported. Windows ML is now GA as the
production on-device runtime on Windows 11. DirectX 12 is required for DirectML (ubiquitous on
modern hardware). Note: Microsoft is steering new Windows ONNX work toward Windows ML over raw
DirectML, so the hardware layer is abstracted (hardware::Backend) to allow swapping the
provider without touching callers. → ADR-0004.
Diarization — sherpa-onnx ✅
sherpa-onnx (k2-fsa) provides offline speaker diarization: pyannote segmentation model +
a speaker-embedding extractor (e.g. 3D-Speaker ERes2Net) + clustering, all as ONNX, fully
offline. It ships C/C++ APIs callable from Rust via FFI. This satisfies "Speaker 1/2 …" labeling
and post-meeting merge/rename without any cloud dependency. → ADR-0005.
Storage — SQLite ✅
SQLite (via sqlx for async or rusqlite for sync) is the standard embedded store, matches
Meetily's proven model, requires no server, and supports full-text search (FTS5) for the
transcript search requirement. → ADR-0006.
Local LLM — Ollama HTTP ✅
Ollama serves a REST API on http://localhost:11434 with /api/chat (OpenAI-style
messages), /api/generate (one-shot), /api/tags (list models), /api/pull (download), and
token streaming via newline-delimited JSON. WA calls only this local endpoint; a "custom
endpoint" option lets advanced users point at any OpenAI-compatible local server. → ADR-0007.
Outlook .pst — outlook-pst / libpff ✅
The Rust outlook-pst crate offers read-only access to PST files modeled on the published
MS-PST specification (emails, folders, and — relevant here — calendar appointments/attendees).
The mature C library libpff (with pffexport) is the fallback for tricky/encrypted files
via FFI or a sidecar. Treat PST strictly as read-only input. → ADR-0008.
External AI / MCP — all targets are MCP clients; Rust SDK exists ✅
- Claude (Code & Desktop): MCP client over stdio + HTTP; Claude Code also runs headless
(
claude -p,--bare) and ships the Claude Agent SDK (Python/TS) — usable for the optional push path. Claude Code can itself act as an MCP server. - OpenAI Codex (CLI): MCP via stdio (local child process) and remote Streamable HTTP
(OAuth/bearer); managed with
codex mcp;codex execfor headless. Has an Agents SDK. - GitHub Copilot: MCP across IDE, CLI, and the cloud agent. Caveat: the cloud agent supports MCP tools only (no resources/prompts) and no OAuth-remote MCP, and runs in GitHub's cloud (can't reach a localhost server) — so WA exposes capabilities as tools, and Copilot cloud is better served by the GitHub-issue handoff.
- OpenCode: full MCP client (local + remote), 75+ LLM providers, has an SDK.
- Transports: MCP defines exactly stdio and Streamable HTTP (HTTP+SSE deprecated). For a
long-running desktop app holding shared state, a loopback Streamable HTTP
/mcpendpoint fits; a thin stdio adapter covers agents that spawn their server. - Rust SDK: the official
rmcpcrate (modelcontextprotocol/rust-sdk, v0.16+,serverfeature) implements tools/resources/prompts with pluggable transports — so WA's Rust core can host the server natively and lightweightly. - Summary APIs: Anthropic is native
/v1/messages(needs its own adapter); OpenAI is/v1/chat/completions; most others are OpenAI-compatible. → ADR-0011 (and ADR-0007 update).
Open items to confirm at build time
- Exact
whisper-rsversion and which acceleration features build cleanly on the Windows CI image. ort↔ ONNX Runtime binary version pinning for the DirectML/NPU path on target Windows builds.outlook-pstcoverage of password-protected and very large PST files; fall back to libpff if gaps.- Whether to consume
sherpa-onnxas a prebuilt C library or build from source in CI.
Sources
- Tauri 2.0 Stable Release · Tauri vs Electron 2026
- whisper-rs (crates.io) · whisper-rs repo
- ort execution providers · ONNX Runtime DirectML EP · Windows ML execution providers
- sherpa-onnx speaker diarization
- wasapi (crates.io) · cpal
- Ollama API docs
- outlook-pst (docs.rs) · libpff
- MCP clients: Copilot MCP + coding agent · Codex MCP · OpenCode MCP/config · Claude Code headless
- MCP protocol: Transports spec · Rust SDK
rmcp(docs.rs) - Summary APIs: Anthropic Messages vs OpenAI Chat Completions