diff --git a/KNOWN-ISSUES.md b/KNOWN-ISSUES.md new file mode 100644 index 0000000..6bf0365 --- /dev/null +++ b/KNOWN-ISSUES.md @@ -0,0 +1,51 @@ +# Known issues + +Tracked limitations and partial implementations in the current codebase. Each entry points at the code that owns the gap so future work can find it. + +## Power management + +### KI-01 — macOS App Nap guard pending Apple Silicon runtime verification + +**Status:** macOS code path compiles and the registry tests pass, but runtime behaviour against actual OS idle-throttling has not been confirmed on Apple Silicon hardware. Also tracked internally as **RB-08**. + +**Source:** [`src-tauri/src/commands/power.rs:73`](src-tauri/src/commands/power.rs#L73) (`PowerAssertion::begin`), [`src-tauri/src/commands/power.rs:140`](src-tauri/src/commands/power.rs#L140) (`objc_bridge`). + +**Impact:** Long live-dictation sessions on macOS may still be slowed or paused by the OS until verified end-to-end on hardware. + +**Workaround:** Keep the app window focused, or move the cursor periodically. For testing, App Nap can be disabled globally with `defaults write NSGlobalDomain NSAppSleepDisabled -bool YES` (revert with `-bool NO`). + +### KI-02 — Linux power assertion is a no-op + +**Status:** `PowerAssertion::begin` does nothing on Linux. The planned implementation (systemd-logind / GNOME idle inhibitor via `org.freedesktop.login1.Inhibit`) is described in the file-level doc but not wired up. + +**Source:** [`src-tauri/src/commands/power.rs`](src-tauri/src/commands/power.rs). + +**Impact:** Long sessions can be paused by the compositor's idle hooks (screen lock, suspend timers) on KDE, GNOME, Hyprland, Sway, etc. + +**Workaround:** Raise the system idle / screen-lock timeout while dictating, or wrap launch with `systemd-inhibit --what=idle:sleep:handle-lid-switch ./run.sh`. + +### KI-03 — Windows power assertion is a no-op + +**Status:** `PowerAssertion::begin` does nothing on Windows. The planned implementation (`SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_AWAYMODE_REQUIRED)` on begin, `ES_CONTINUOUS` alone on end) is described in the file-level doc but not wired up. + +**Source:** [`src-tauri/src/commands/power.rs`](src-tauri/src/commands/power.rs). + +**Impact:** Long sessions can be paused by Windows sleep policies. + +**Workaround:** Set the active power plan's sleep to "Never" while dictating. + +## Cloud providers + +### KI-04 — `magnotia-cloud-providers` crate is not user-exposed + +**Status:** The crate is a declared workspace dependency in [`src-tauri/Cargo.toml:36`](src-tauri/Cargo.toml#L36) and compiles into the binary, but no Tauri command, page, or settings field invokes `store_api_key` / `retrieve_api_key`. There is no UI to enter or store a cloud API key in the current build. + +**Source:** [`crates/cloud-providers/src/keystore.rs`](crates/cloud-providers/src/keystore.rs). The `TODO` in the doc comment captures the planned migration to OS-native credential storage (the `keyring` crate or equivalent) before the feature is wired up. + +**Impact:** None for end users today (no exposed surface). When the feature is wired post-launch, cross-restart persistence must land before any "save key" UX ships, otherwise saved keys reset on every restart. + +**Workaround:** N/A. + +## How to add an entry + +When shipping a partial implementation or known limitation, add a `KI-NN` entry here with the four standard fields: **Status**, **Source** (file:line), **Impact**, **Workaround**. Link from the affected module's doc comment back to this file by ID. diff --git a/README.md b/README.md index 536e894..596bd7c 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ Magnotia is a local-first, cognitive-load-aware dictation and task-capture deskt - Current `main`: see commit log - 9 library crates plus the Tauri app crate; 220+ lib tests plus 67 Tauri-app tests, all passing - Cross-platform CI (Linux / macOS / Windows) via GitHub Actions +- Tracked limitations live in [`KNOWN-ISSUES.md`](KNOWN-ISSUES.md) --- @@ -235,10 +236,10 @@ Utility modules in the same directory (no `#[tauri::command]` attributes; helper | Platform | Status | Notes | |---|---|---| -| Linux Wayland (KDE Plasma, GNOME Mutter, Hyprland, Sway) | **Primary target**, daily-dogfooded on KDE | evdev hotkey, GTK 3 via webkit2gtk, Vulkan, all paste backends | -| Linux X11 | Supported | xdotool paste path, GTK 3 | -| macOS | In CI, untested runtime | osascript paste, Metal via MoltenVK, App Nap guard | -| Windows | In CI, untested runtime | SendKeys paste, Vulkan-first GPU path, bundled DLLs for CPU fallback | +| Linux Wayland (KDE Plasma, GNOME Mutter, Hyprland, Sway) | **Primary target**, daily-dogfooded on KDE | evdev hotkey, GTK 3 via webkit2gtk, Vulkan, all paste backends; idle inhibit not wired (see KI-02) | +| Linux X11 | Supported | xdotool paste path, GTK 3; idle inhibit not wired (see KI-02) | +| macOS | In CI, untested runtime | osascript paste, Metal via MoltenVK, App Nap guard pending Apple Silicon verification (see KI-01) | +| Windows | In CI, untested runtime | SendKeys paste, Vulkan-first GPU path, bundled DLLs for CPU fallback; sleep prevention not wired (see KI-03) | CI runs `cargo check --workspace --all-targets` + `svelte-check` on all three on every push and PR. @@ -336,6 +337,7 @@ Cross-repo survey of 10 OSS Whisper projects, the Magnotia-specific atomic task ### Dev reference - [`docs/dev-setup.md`](docs/dev-setup.md) — dependency + launch reference - [`docs/icon-mapping.md`](docs/icon-mapping.md) — icon conventions +- [`KNOWN-ISSUES.md`](KNOWN-ISSUES.md) — tracked partial implementations and limitations --- diff --git a/src-tauri/src/commands/power.rs b/src-tauri/src/commands/power.rs index aa6d33a..241aef1 100644 --- a/src-tauri/src/commands/power.rs +++ b/src-tauri/src/commands/power.rs @@ -10,16 +10,25 @@ //! pin the process into a "latency-critical, user-initiated" state for //! the duration of a live session or an LLM generation. The returned //! activity object must be retained; dropping it ends the assertion. +//! Runtime verification on Apple Silicon against actual idle-throttling +//! is still pending. See `KNOWN-ISSUES.md` (KI-01). //! -//! On Linux we inhibit systemd-logind / GNOME session idle via -//! org.freedesktop.login1 where available. On Windows we call -//! `SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | -//! ES_AWAYMODE_REQUIRED)` on begin and `ES_CONTINUOUS` alone on end. +//! On Linux and Windows, `PowerAssertion::begin` is currently a no-op +//! that registers a snapshot in the process-wide registry for diagnostics +//! but does not inhibit OS-level idle throttling. The planned +//! implementations are: //! -//! All paths degrade to no-ops without failing — a missing DBus session -//! or an unsupported Cocoa binding is not fatal, it just means the OS -//! may still decide to idle us. We log when that happens so the -//! diagnostics bundle has a breadcrumb. +//! - Linux: systemd-logind / GNOME session idle inhibit via +//! `org.freedesktop.login1.Inhibit` where available. +//! - Windows: `SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED +//! | ES_AWAYMODE_REQUIRED)` on begin and `ES_CONTINUOUS` alone on end. +//! +//! Until those land, long sessions on Linux and Windows can still be +//! idled by the OS. See `KNOWN-ISSUES.md` (KI-02, KI-03) for workarounds. +//! +//! All paths return a guard so the caller's code is unchanged. Failures +//! to acquire a real assertion are logged so the diagnostics bundle has +//! a breadcrumb. use std::collections::HashMap; use std::sync::atomic::{AtomicUsize, Ordering};