fix: model-loaded guards on transcribe_pcm, power assertion guards on tasks LLM commands

transcribe_pcm and transcribe_pcm_parakeet did not check that their
respective engines were loaded before clone+spawn_blocking. transcribe_file
already calls ensure_model_loaded; these now mirror that posture with a
friendly error when the engine is unloaded, matching what
extract_content_tags_cmd does.

decompose_and_store and extract_tasks_from_transcript_cmd ran multi-second
LLM inference inside spawn_blocking without the PowerAssertion guard that
cleanup_transcript_text_cmd and extract_content_tags_cmd already use. Both
now begin a guard so the macOS App-Nap inhibitor (and the planned
Linux/Windows equivalents per KI-02, KI-03) can pin the process for the
duration of the inference.

HANDOVER.md gets a status note clarifying it captures Phase 9 state. The
schema head referenced (v14) was the head at session time; current head
is v15 (`idx_transcripts_profile_created` composite index) per the
architecture map.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
jars
2026-05-09 15:47:48 +01:00
parent e5e12387e8
commit 2a45cb8033
3 changed files with 21 additions and 4 deletions

View File

@@ -7,6 +7,8 @@ description: Session handover — 2026/04/24-25 Phase 9 polish debt mostly shipp
# Magnotia Handover — 2026/04/25
> **Note:** Session-specific handover. Migration v14 (`transcripts.llm_tags`) was the head **at the time of this session**. Subsequent work has advanced the schema; current head is v15 (`idx_transcripts_profile_created`, composite index). For the current codebase shape, see [`docs/architecture-map/`](docs/architecture-map/) and [`KNOWN-ISSUES.md`](KNOWN-ISSUES.md).
Phase 9 session. Spec + plan written from scratch and committed; plan corrections layered in after critical review against the actual codebase (Codex was unreachable for cross-model review, three retries failed at the ChatGPT-account-entitlement layer). Sub-phases 9a + 9b + sparkline polish landed end to end. Sub-phase 9c reduced to the Phase 8 carryover bug fix; sub-phase 9d's walkthrough sweeps deferred to Phase 10a QC.
## Rebrand note

View File

@@ -18,6 +18,7 @@ use magnotia_storage::{
FeedbackRow, FeedbackTargetType, TaskRow,
};
use crate::commands::power::PowerAssertion;
use crate::AppState;
/// Frontend-facing task shape. Matches the in-memory object in page.svelte.js.
@@ -319,6 +320,7 @@ pub async fn decompose_and_store(
let engine = state.llm_engine.clone();
let parent_text = parent.text.clone();
let steps = tokio::task::spawn_blocking(move || {
let _power_guard = PowerAssertion::begin("magnotia LLM micro-step decomposition");
engine.decompose_task_with_feedback(&parent_text, &examples)
})
.await
@@ -361,10 +363,13 @@ pub async fn extract_tasks_from_transcript_cmd(
.unwrap_or_default();
let engine = state.llm_engine.clone();
tokio::task::spawn_blocking(move || engine.extract_tasks_with_feedback(&transcript, &examples))
.await
.map_err(|e| e.to_string())?
.map_err(|e| e.to_string())
tokio::task::spawn_blocking(move || {
let _power_guard = PowerAssertion::begin("magnotia LLM task extraction");
engine.extract_tasks_with_feedback(&transcript, &examples)
})
.await
.map_err(|e| e.to_string())?
.map_err(|e| e.to_string())
}
#[tauri::command]

View File

@@ -154,6 +154,11 @@ pub async fn transcribe_pcm(
profile_id: Option<String>,
) -> Result<(), String> {
ensure_main_window(&window)?;
if !state.whisper_engine.is_loaded() {
return Err(
"Whisper model not loaded. Download a Whisper model in Settings.".to_string(),
);
}
let resolved_profile_id =
profile_id.unwrap_or_else(|| magnotia_storage::DEFAULT_PROFILE_ID.to_string());
@@ -352,6 +357,11 @@ pub async fn transcribe_pcm_parakeet(
profile_id: Option<String>,
) -> Result<(), String> {
ensure_main_window(&window)?;
if !state.parakeet_engine.is_loaded() {
return Err(
"Parakeet model not loaded. Enable Parakeet in Settings.".to_string(),
);
}
let resolved_profile_id =
profile_id.unwrap_or_else(|| magnotia_storage::DEFAULT_PROFILE_ID.to_string());