--- name: 2026-05-14-phase-b-dogfood-plan type: plan tags: [phase-b, dogfood, code-atomiser-fix, verification, lumotia] description: "Plan for Phase B of the post-rebrand dogfood pass — verify the 25+ code-atomiser-fix commits (race conditions, lifecycle, trust-boundary, time bombs, observability) against gaps the original commits did not close. Per-item methodology: orient on the commit, survey existing coverage, identify real residuals, surgical fix or documented pass, commit. Phase A (rebrand-migration verification) shipped six commits including a real silent-data-loss bug fix surfaced by the dogfood drill." --- # Phase B dogfood plan — code-atomiser-fix wave **Started:** 2026/05/14 **Owner:** Wren (with Jake oversight) **Status:** In progress. B.1 done. B.2–B.15 pending. --- ## Context Phase A (rebrand-migration verification) shipped six commits including a real silent-data-loss bug fix surfaced by `scripts/dogfood-rebrand-drill.sh`. Phase B applies the same methodology to the 25+ code-atomiser-fix commits that landed between the rebrand cascade and the supply-chain pre-flight: examine each, confirm what the commit claims to fix, identify gaps the original test+fix pass missed, write tests or fix residuals where real, and commit per-item so the audit trail stays surgical. **Phase A baseline gates carried into Phase B:** - `cargo test --workspace` — 409 pass / 0 fail - `cargo fmt --check` — clean - `cargo clippy --workspace --all-targets -- -D warnings` — clean - `npm run test` — 12 / 12 - `npm run check` — 0 / 0 - `scripts/dogfood-rebrand-drill.sh` — 8 / 8 probes - Rust toolchain pinned to 1.94.1 stable - npm dev deps pinned exact Each B.x commit must keep all of the above green. ## Methodology per item For each B.x: 1. **Orient.** Read the commit metadata (subject, body, files changed) and the relevant code in its current state. 2. **Survey.** Catalogue existing test coverage and identify what is *not* tested. 3. **Decide.** Real residual found? Surgical fix or test. No residual? Document the verdict and move on. Hard-to-fixture gap acknowledged in code? Honour the original author's SAFETY annotation and document the pass. 4. **Verify.** Run the per-crate or per-area test gate plus workspace clippy + fmt before committing. 5. **Commit.** Format: `agent: lumotia — Phase B.x `. Include findings + verdict + verification gates in the body. ## Items | # | Surface | Commit(s) | Status | Outcome | |---|---|---|---|---| | **B.1** | Cancellable Whisper inference + bounded drain + lock-over-await | `5725836` | **Done** (`6c212a0`) | 8 existing unit tests cover the atomiser-targetable surface. Race-B end-to-end test acknowledged as hard-to-fixture in the SAFETY comment and left as-is. One real residual fixed: misleading comment on `start_live_transcription_session` claiming lifecycle is "Released explicitly before the RunningLiveSession is installed" — the code does the safer opposite (install-while-locked, drop after). Future reader would have trusted the comment and "fixed" the code into a regression. | | **B.2** | Hotkey supervisor rearchitecture | `1068ad9` (Race-1, Race-2, TOCTOU) | Pending | — | | **B.3** | Atomic model download + manifest | `9f67ab2` (Rev-1, Rev-5) | Pending | — | | **B.4** | Soft-delete + trash + restore | `15b74db`, `87e6248`, `50d0715`, `99f4ecd` (Rev-2, Rev-3) | Pending | — | | **B.5** | `write_text_file_cmd` path scoping + `transcribe_file` extension allowlist + size cap | `a2b47db`, `a48653c`, `b3da58c` (Trust-1) + `9653e25` (Trust-5) + `ed449cc` (Trust-2) | Pending | — | | **B.6** | Main-window guards on clipboard / extract-tags / file-write | `12b413d`, `f7af7b0` (Trust-4), `7aee534` (Trust-3, Trust-6) | Pending | — | | **B.7** | LlmEngine critical-section narrowing + drop-old-model-first | `cde985d` (Race-3, Lifecycle-1) | Pending | — | | **B.8** | Span propagation across live + model-load spawns; `lumotia.log` writer + EnvFilter coverage; drop `lumotia_live` literal target | `65abfa2` (Obs-3), `8becb1a` (Obs-4, Obs-5), `d1391b3` (Obs-1, Obs-2) | Pending | — | | **B.9** | JSON-envelope LLM extractor (GBNF removal) | `1d71e8e` | Pending | — | | **B.10** | `focusTimer` rehydrate `startTick` invariant | `5ba761a` (Race-10) | Pending | — | | **B.11** | `FirstRunPage` unlisten on all exits | `6aa6a43` (Race-9) | Pending | — | | **B.12** | `Transcriber::transcribe_sync_with_abort` required | `e0e9a6e` (Lifecycle-2) | Pending | — | | **B.13** | `drain_inference` deadline from `task.duration_secs` | `07f6755` (Time-bomb-1) | Pending | — | | **B.14** | Surface capture-thread drops + bypass validation requeue cap | `094b533` | Pending | — | | **B.15** | `test_llm_model` respects caller GPU preference | `afbd33d` (Race-8) | Pending | — | ## Anti-patterns to avoid - **Over-refactoring for testability.** B.1 had a legitimate Race-B gap that would require restructuring `LiveSessionRuntime` to test in isolation. The original author flagged the trade-off and chose to keep the production shape simple. We honour that — invasive refactor for one test risks introducing the bug the test would have caught. - **Re-running the dogfood drill mid-Phase-B.** The drill is in place for Phase A's domain (rebrand migration). Phase B touches different surfaces. Adding new drills is in scope if a real residual demands one (per B.1 — none did). - **Batch-survey-then-fix.** One-at-a-time per Jake's "utmost care" instruction. Each item gets a focused commit; future reviewer can stop at any boundary without untangling a multi-item changeset. ## Done items ### B.1 — start_live lifecycle comment fix (`6c212a0`) **Surface:** `src-tauri/src/commands/live.rs`. The `start_live_transcription_session` function's upper comment (lines 705-711) claimed `Released explicitly before the RunningLiveSession is installed in live_state.running`. The actual code installs RunningLiveSession on lines 801-806 and only drops `lifecycle` on line 811. The safer ordering — install-while-locked, then release — was already in place; only the comment was wrong. **Why it matters:** A future reader auditing the locking discipline would have trusted the comment over the code and "fixed" the code to match the buggier description — reintroducing the half-initialised window where a concurrent `stop_live` could observe `running == None` while a `start_live` is mid-install. **Other findings (no fix needed):** * 8 existing unit tests cover the atomiser-targetable surface (`dropping_inference_task_sets_abort_flag`, `drain_timeout_scales_with_inflight_chunk_duration_secs`, `drain_timeout_honours_floor_for_short_chunks`, `drain_timeout_uses_floor_when_no_inflight_task`, `drain_timeout_rejects_non_finite_duration`, `result_listener_loss_is_warned_once_and_not_treated_as_inference_failure`, `dead_result_and_status_channels_self_assert_stop_flag`, `no_lumotia_live_literal_target_in_live_rs`). * The Race-B drain-timeout end-to-end test gap is genuine but acknowledged in the SAFETY comment inside `drain_inference`. Closing it requires either extracting the inner logic into a pure function with explicit dependencies (refactor of working production code) or constructing a full synthetic `LiveSessionRuntime` (impractical — needs a real engine + model + audio device). Honour the original author's call. * `stop_live_transcription_session` comments + code consistent. No fix needed. **Verification:** `cargo test -p lumotia --lib commands::live` 17 / 17 (unchanged, comment-only edit); clippy + fmt clean.