Phase 9 of the rebrand cascade. Sweep covers everything the Phase 8
frontend pass deliberately skipped: docs/, root markdown, scripts,
Cargo.toml descriptions, code comments that survived earlier
word-boundary sed, plus a handful of identifiers caught on the final
verify pass.
transcription-app changes:
- README.md, HANDOVER.md, KNOWN-ISSUES.md, run.sh — magnotia/Magnotia
-> lumotia/Lumotia.
- docs/ — sweep across all subdirs except docs/handovers/ (preserved
as immutable audit trail). Includes architecture-map references
to magnotia_core::*, magnotia_storage::*, etc. now pointing at
lumotia_*; dev-setup.md tracing output examples (lumotia_startup
target); brief/ + superpowers/ + issues/ + whisper-ecosystem/ +
audit/.
- Cargo.toml descriptions on 9 crates (core, audio, cloud-providers,
hotkey, llm, mcp, plus referenced others).
- crates/core/src/{error,hardware,recommendation,paths}.rs +
crates/audio/src/wav.rs + crates/llm/src/model_manager.rs +
crates/cloud-providers/src/keystore.rs + crates/mcp/src/lib.rs —
doc comments and a model-manager user-agent string.
- Caught on final pass: BroadcastChannel("magnotia_task_sync") -> ...
("lumotia_task_sync"); magnotia_locale i18n localStorage key
renamed + migration shim added; CSS keyframe names
magnotiaPulse / magnotiaBar / magnotiaFade renamed in the design-
system kit; magnotia_viewer_item / magnotia_viewer_mode handoff
keys renamed in HistoryPage + viewer/+page.svelte; src/assets/
wordmark.svg text.
- src-tauri/src/lib.rs comment cleanup ("magnotia era" was sed'd
to "lumotia era" earlier — restored).
Preserved (intentional):
- crates/core/src/paths.rs — keeps "magnotia" / "Magnotia" / ".magnotia"
legacy detection strings in legacy_and_target_paths() so the
migration shim can still find user data from the magnotia era.
- src/lib/stores/{page,focusTimer}.svelte.ts + src/lib/i18n/index.ts
— migration call sites reference the legacy magnotia keys
deliberately.
- docs/handovers/ — historical audit trail.
cargo build --workspace passes. npm run check: 0 errors / 0 warnings
(3958 files). cargo test --workspace: 339 pass / 0 fail.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7.8 KiB
name, type, slice, last_verified
| name | type | slice | last_verified |
|---|---|---|---|
| Tests and fixtures | architecture-map-page | 03-audio-transcription | 2026/05/09 |
Tests and fixtures
Where you are: Architecture map → Audio + Transcription → Tests and fixtures
Plain English summary. This slice has three categories of test. Inline unit tests under #[cfg(test)] mod tests exercise every public type (capture monitor detection, resampler duration preservation, RmsVadChunker state machine, LocalAgreement invariants, buffer trim bounds, model-manager hash and resume paths). Integration tests under crates/transcription/tests/ exercise whisper-rs end-to-end with env-var-gated fixtures so CI without a model checkpoint exits quietly. Test-only fixtures include in-tree tokio::net::TcpListener HTTP servers that simulate Range / 5xx / no-Range-honour servers for the download stack.
At a glance
- Crate:
lumotia-transcription(mostly) andlumotia-audio(inline only). - Paths:
crates/audio/src/{capture,decode,wav,resample,streaming_resample}.rs— inline#[cfg(test)]modules.crates/transcription/src/{model_manager,local_engine,transcriber,streaming/*}.rs— inline#[cfg(test)]modules.crates/transcription/tests/whisper_rs_smoke.rs— env-gated load + transcribe.crates/transcription/tests/jfk_bench.rs— env-gated benchmark with cold/warm RTF.crates/transcription/tests/thread_sweep.rs— env-gated thread-count scaling sweep.
- External deps (dev):
tempfile 3,tokio(rt, sync, net, io-util, macros),num_cpus 1(label-only).
Inline unit tests (selected highlights)
lumotia-audio
capture.rs:570—monitor_pattern_detectionfor the PulseAudio / PipeWire heuristics.decode.rs:262—mid_stream_io_error_propagates_instead_of_returning_partial_audio. RB-09 regression: a flakyMediaSource(FlakyCursor,decode.rs:203) injects an I/O error after the probe header and asserts the function errors instead of returningOk(partial).wav.rs:170—wav_writer_survives_crash. Usesstd::mem::forgetto skip the hound finaliser, simulating a process kill, then asserts the flushed prefix is recoverable viaread_wav.wav.rs:235—read_wav_surfaces_truncated_sample_stream_errors. 2026-04-22 regression: the previousfilter_map(|s| s.ok())swallowed errors silently.streaming_resample.rs:182—streaming_48k_to_16k_preserves_duration. Pushes 1 s of 48 kHz audio in 700-sample chunks (forcing the residual-buffer path) and asserts the output is within 50 ms of 1 s at 16 kHz.resample.rs:84—resample_preserves_approximate_duration.
lumotia-transcription
streaming/rms_vad.rs:371–:734— comprehensive state-machine coverage: silence, hysteresis, onset gating, max-chunk continuity (max_chunk_split_preserves_audio_contiguity), padded-final-frame regression (flush_preserves_hit_max_chunk_from_padded_final_frame,flush_preserves_end_of_utterance_chunk_from_padded_final_frame— both 2026-04-22 CRITICAL C2 fixes), idempotent flush.streaming/commit_policy.rs:212–:402— LocalAgreement-n correctness: text-only equality, non-shrinkage invariant, defensive shorter-pass handling (shorter_pass_after_commit_does_not_panic, regression for thelatest[committed_count..]panic), n=3 behaviour.streaming/buffer_trim.rs:56–:206— defensive non-finite handling, integration test againstLocalAgreement::last_committed_end_secs, the long-session bound proof (trim_bounds_buffer_over_long_session).model_manager.rs:339–:615— three TcpListener-backed fixtures (spawn_range_server,spawn_no_range_server,spawn_500_server) drivedownload_filethrough the resume path, the ResumeUnsupported path (server returns 200 to a Range request), the 5xx rejection path, and the SHA-mismatch cleanup path.local_engine.rs:218—engine_reports_not_available_before_loading.transcriber.rs:54—transcriber_trait_is_object_safe(compile-time witness).
Env-gated integration tests (crates/transcription/tests/)
All three skip silently if the env vars are unset, so cargo test on a fresh machine is a no-op for them.
whisper_rs_smoke.rs
- Env vars:
MAGNOTIA_WHISPER_TEST_MODEL(path to a ggml/gguf Whisper model). - Loads the context, builds a state, calls
set_initial_prompt("Wren, CORBEL, ADHD")(proves the API still exists), runs inference on 1 s of silence, exercisesfull_n_segmentsandget_segment(i).to_str(). Smoke test only; assertion is "did this run without panicking".
jfk_bench.rs
- Env vars:
MAGNOTIA_WHISPER_TEST_MODEL,MAGNOTIA_WHISPER_TEST_AUDIO(path to a 16 kHz mono 16-bit PCM WAV — assertions in the test enforce this format on the fixture, not the runtime). - Reports cold-load time, cold-transcribe RTF, warm-transcribe RTF, peak RSS read from
/proc/{pid}/status. Hardcodesset_n_threads(6)for both runs (so a sweep across thread counts is a separate test, not this one).
thread_sweep.rs
- Same env vars as
jfk_bench.rs. AddsMAGNOTIA_POWER_STATE_OVERRIDE(set internally per panel toacorbattery) soinference_thread_countreturns its predicted pick for each combination of (power state × GPU offload) and the empirical RTF table can be compared against the helper's choice. - Runs the JFK clip at
n_threads = 1, 2, 4, physical, logical(plus8if logical ≥ 8), takes the min of two runs per setting, prints a four-panel table:- AC, CPU.
- AC, GPU (Vulkan).
- battery, CPU.
- battery, GPU (Vulkan).
- Uses
num_cpus::get()andnum_cpus::get_physical()purely for the printed labels (thread_sweep.rs:35). The runtime helperinference_thread_count(Workload::Whisper, gpu_offloaded)does the actual prediction. vulkan_runtime_oksnapshot taken once viacfg!(feature = "whisper-vulkan") && vulkan_loader_available().
Watch-outs
- All three integration tests are quiet on missing env vars. A green
cargo testdoes NOT mean the Whisper path works; it means "either the path works or you didn't set the env vars". CI configurations must explicitly setMAGNOTIA_WHISPER_TEST_MODELto exercise these. jfk_bench.rshardcodesn_threads = 6. Production code usesinference_thread_count(Workload::Whisper, gpu_offloaded)which is power-aware. Bench numbers are not directly comparable to runtime numbers without rerunning with the helper-picked thread count.thread_sweep.rsmutatesMAGNOTIA_POWER_STATE_OVERRIDEviaenv::set_var. Globally process-wide. Concurrent tests in the samecargo testinvocation that readMAGNOTIA_POWER_STATE_OVERRIDEwill race. The test removes the var at the end (thread_sweep.rs:94).tempfile 3is a dev-dep, not a runtime dep. Production code never creates temp files.num_cpus = "1"(the version, not "one CPU"). Test-only labelling; production uses the slice 5 helper.- In-tree HTTP fixtures use ephemeral ports (
bind 127.0.0.1:0) and run on a tokio task. No port-collision risk, but a paranoid sandbox that blocks raw TCP loopback would break these tests. ModelFile's&'static strfields force the test helperleak()(model_manager.rs:462). Each test leaks a few small strings. Acceptable for one-shot tests; do not copy this pattern into production code.
See also
- Transcription model manager — the production code these download tests guard.
- Transcription whisper — the production code these integration tests guard.
- Transcription streaming — exhaustive unit-test coverage lives alongside this code.
docs/whisper-ecosystem/brief.md— the source of the items (#6, #8, #19, #21, #24, #25) repeatedly referenced in test docstrings.docs/code-review-2026-04-22.md— the audit pass that produced the C2, RB-09, andread_wavregressions captured here.