Codex independent review found 11 blockers post-cascade. All addressed.
CRITICAL (data-loss / crash):
10. crates/core/src/paths.rs — migrate_legacy_data_dir_inner used
fs::rename which fails with EXDEV when source + target are on
different filesystems (encrypted-home, bind mounts, separate
$XDG_DATA_HOME partition). Combined with the Phase 5 QC fix that
made migration errors fatal, this would crash on first launch
for any user whose data dir spans filesystems. Added
rename_or_copy_tree() that falls back to copy_dir_recursive +
remove_dir_all on CrossesDevices / errno 18 (EXDEV). Symlinks
preserved verbatim. Same fallback applied to magnotia.db ->
lumotia.db inside the dir.
11. Added 4 unit tests: copy_dir_recursive preserves nested
structure, rename_or_copy_tree same-filesystem happy path,
is_cross_device classifies CrossesDevices kind + raw errno 18.
Doc residuals (blockers 1-9):
1. crates/cloud-providers/Cargo.toml — "Wyrdnote pending rebrand"
description.
2. crates/cloud-providers/src/provider.rs — module docs + test
fixture Wyrdnote refs.
3. crates/transcription/src/orchestrator.rs — module docs + test
fixture Wyrdnote refs.
4. docs/roadmap/2026-05-10-pkm-phase-tooling-shortlist.md — phase
name + outputs/wyrdnote path refs.
5. docs/architecture-map/04-llm-formatting-mcp/llm-tests.md —
MAGNOTIA_LLM_TEST_MODEL env var.
6. .../cloud-providers-stubs.md — MAGNOTIA_API_KEY_*.
7. docs/architecture-map/03-audio-transcription/tests-and-fixtures.md
— MAGNOTIA_WHISPER_*.
8. docs/gpu-tuning/plan.md — MAGNOTIA_BENCH_RUN.
9. docs/superpowers/specs/2026-05-09-battery-gpu-aware-thread-tuning-
design.md + corresponding plan — MAGNOTIA_POWER_STATE_OVERRIDE,
MAGNOTIA_INFERENCE_THREADS.
cargo test --workspace: 343 pass / 0 fail (up from 339; +4 EXDEV
fallback tests).
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:
LUMOTIA_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:
LUMOTIA_WHISPER_TEST_MODEL,LUMOTIA_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. AddsLUMOTIA_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 setLUMOTIA_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.rsmutatesLUMOTIA_POWER_STATE_OVERRIDEviaenv::set_var. Globally process-wide. Concurrent tests in the samecargo testinvocation that readLUMOTIA_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.