agent: lumotia-rebrand — fix Codex cross-model review blockers
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>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
//! `Orchestrator` is the single entry point for transcription. Tauri
|
||||
//! commands resolve a provider through it; nothing else calls a
|
||||
//! provider directly. This is where the AGPL OEM trait boundary meets
|
||||
//! Wyrdnote's local engines.
|
||||
//! Lumotia's local engines.
|
||||
//!
|
||||
//! `LocalProviderAdapter` lives here, not as an `impl
|
||||
//! TranscriptionProvider for LocalEngine`. The adapter wraps an
|
||||
@@ -223,7 +223,7 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn orchestrator_dispatches_to_named_provider() {
|
||||
let calls = Arc::new(AtomicUsize::new(0));
|
||||
let registry = build_registry_with("canned", "hello wyrdnote", calls.clone());
|
||||
let registry = build_registry_with("canned", "hello lumotia", calls.clone());
|
||||
let orchestrator = Orchestrator::new(registry);
|
||||
|
||||
let profile = EngineProfile::new(ProviderId::new("canned"));
|
||||
@@ -232,7 +232,7 @@ mod tests {
|
||||
.await
|
||||
.expect("dispatch succeeds");
|
||||
|
||||
assert_eq!(result.transcript.text(), "hello wyrdnote");
|
||||
assert_eq!(result.transcript.text(), "hello lumotia");
|
||||
assert_eq!(result.inference_ms, 7);
|
||||
assert_eq!(calls.load(Ordering::SeqCst), 1);
|
||||
}
|
||||
@@ -264,7 +264,7 @@ mod tests {
|
||||
|
||||
let mut profile = EngineProfile::new(ProviderId::new("canned"));
|
||||
profile.language = Some("en".to_string());
|
||||
profile.initial_prompt = Some("Wyrdnote".to_string());
|
||||
profile.initial_prompt = Some("Lumotia".to_string());
|
||||
|
||||
let _ = orchestrator
|
||||
.transcribe(one_second_of_silence(), &profile)
|
||||
|
||||
Reference in New Issue
Block a user