Captures the 12 items from docs/code-review-2026-04-22.md that must land before v0.1 ships. One markdown file per issue with: severity, path:line, problem description, acceptance criteria, fix scope, and dependency graph. Split by severity: - 3 CRITICAL: live-session race, migration atomicity, transcript- profile FK - 9 MAJOR: monolith refactor, channel-fatality, capture worker join, runtime capabilities, macOS App Nap, decoder error prop, LLM prompt preflight, keystore thread-safety, hotkey device filter README.md indexes them with a fix-order dependency graph and a fish-shell script for bulk-converting to GitHub issues once `gh` CLI is installed and authed. Deferred step by user decision — markdown tracker is authoritative until then.
30 lines
1.6 KiB
Markdown
30 lines
1.6 KiB
Markdown
# RB-01 CRITICAL: racy single-session guard in live.rs
|
|
|
|
**Severity:** CRITICAL
|
|
**Path:** `src-tauri/src/commands/live.rs:193-338`
|
|
**Source:** [2026-04-22 code review](../code-review-2026-04-22.md#c1--racy-single-session-guard-in-livers)
|
|
**Labels:** release-blocker, critical, concurrency
|
|
|
|
## Problem
|
|
|
|
`start_live_transcription_session` checks `running` is `None` before multiple `await`s and only stores the handle at the end. `stop_live_transcription_session` removes `running` before awaiting the worker join. Two overlapping IPC calls can:
|
|
|
|
- Admit a second live session (start sees `running == None`, awaits, another start fires in the gap, both proceed)
|
|
- Expose an empty slot while the first session is still shutting down (stop removes the handle, awaits, a fresh start runs against the incoherent state)
|
|
|
|
This breaks the file's core invariant that only one microphone/live session exists at a time.
|
|
|
|
## Acceptance
|
|
|
|
- Hold the session-slot lock (or a semaphore) across the async boundary so no two `start`/`stop` IPC calls can interleave.
|
|
- Regression test: fire two `start_live_transcription_session` IPC calls concurrently; exactly one must succeed and the other must error cleanly.
|
|
- Regression test: during an in-flight `stop`, a concurrent `start` must block until the previous session's worker has fully joined.
|
|
|
|
## Fix scope
|
|
|
|
Large. Will likely require the `run_live_session` monolith refactor (RB-04) to land first so the state machine is small enough to reason about under the lock discipline.
|
|
|
|
## Dependencies
|
|
|
|
- **Blocked by:** RB-04 (`run_live_session` monolith refactor)
|