Closes the code-side v0.1 ship gate. All quality gates green: cargo fmt/clippy/test (~327 tests), npm check (0/0), vitest 13/13, scripts/dogfood-rebrand-drill.sh 8/8. Phase F — first-run onboarding promoted to v0.1 - FirstRunPage with skip-to-main + failure recovery + event recording - Six onboarding commands (record/list/has-completed + lumotia_events) - Storage migration v17 (onboarding_events + lumotia_events tables) UI hardening (in-scope items from v0.1-ui-hardening.md) - StatusPill + PostCaptureCard components, 21st preview entry - Sidebar recording-as-sacred-state (opacity + aria-disabled, reduced-motion) - Settings 6-section regroup + Help section + Activation log + Privacy toggle - Error-state copy sweep (DictationPage + SettingsPage, plain-language) - Global :focus-visible rule, textarea outlines restored - Ctrl+K / Ctrl+, / Escape bindings in +layout LLM resilience - rule_based_extract_tasks (regex-free imperative-verb extractor) + extract_tasks_with_fallback wrapper — task extraction never returns zero - tokio::time::timeout(120s) wraps cleanup/tags/tasks commands Release artefacts - LICENSE (canonical AGPL-3.0), CHANGELOG (Keep-a-Changelog format) - v0.1-release-notes, privacy-and-ai-use, install-warnings, tester-onboarding-kit, tester-acceptance-runbook, code-signing-setup, apple-silicon-rb08-runbook, virtual-audio-setup, v0.1-contrast-audit - Workspace versioning + AGPL spdx; npm exact-pin (10 ranges removed) - AppImage SHA-256 sidecar in build.yml - README v0.1 section + Reporting-issues; canonical repo slug Closure pass — items moved from human-required to code-complete - KI-02 Linux idle inhibit: zbus 5 → org.freedesktop.login1.Manager.Inhibit - KI-03 Windows sleep prevention: SetThreadExecutionState(ES_CONTINUOUS|...) - acquire/release_idle_inhibit Tauri commands, wired in DictationPage - Diagnostic-bundle frontend wire-up (Settings → Help button) - WCAG-AA contrast fix via .btn-filled-text utility (no token changes) - 8 destructive-action sites wrapped in plain-language confirm() guards - KNOWN-ISSUES.md + v0.1-known-limitations.md updated (KI-02/03 fixed) Scripts - pre-tag-verify.sh, tag-day.sh, smoke-linux + driver - parse-diagnostic-bundle.sh, parse-activation-log.py Per-item audit trail: docs/release/v0.1-completion-status.md Remaining: W-01…W-08 (signing certs, hardware probes, smoke matrix, tester recruitment) — see docs/release/v0.1-known-limitations.md.
89 lines
7.6 KiB
Markdown
89 lines
7.6 KiB
Markdown
# 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 idle inhibit ✓ fixed in v0.1
|
|
|
|
**Status:** Resolved. `acquire_idle_inhibit` now calls `org.freedesktop.login1.Manager.Inhibit`
|
|
via zbus (blocking, offloaded to `spawn_blocking`) on recording start, holding the returned file
|
|
descriptor. `release_idle_inhibit` closes the fd on recording stop, which atomically releases the
|
|
lock. The inhibit scope is `idle:sleep:handle-lid-switch` in `block` mode.
|
|
|
|
If D-Bus is unavailable (non-systemd containers, exotic distros), the call fails gracefully with a
|
|
`tracing::warn!` and recording continues — the workaround below remains valid in those edge cases.
|
|
|
|
**Source:** [`src-tauri/src/commands/power.rs`](src-tauri/src/commands/power.rs) (`acquire_idle_inhibit`, `release_idle_inhibit`, `linux_inhibit` mod).
|
|
|
|
**Workaround (edge cases only):** Wrap launch with `systemd-inhibit --what=idle:sleep:handle-lid-switch ./run.sh` if logind is not available.
|
|
|
|
### KI-03 — Windows sleep prevention ✓ fixed in v0.1
|
|
|
|
**Status:** Resolved. `acquire_idle_inhibit` now calls
|
|
`SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED)` on recording start.
|
|
`release_idle_inhibit` calls `SetThreadExecutionState(ES_CONTINUOUS)` to restore normal behaviour.
|
|
Display sleep is intentionally NOT blocked — the user is dictating, not watching the screen.
|
|
|
|
**Source:** [`src-tauri/src/commands/power.rs`](src-tauri/src/commands/power.rs) (`acquire_idle_inhibit`, `release_idle_inhibit`, `windows_inhibit` mod).
|
|
|
|
**Workaround (edge cases only):** If the power plan has a policy override that blocks `SetThreadExecutionState`, set the active sleep timeout to "Never" while dictating.
|
|
|
|
## Cloud providers
|
|
|
|
### KI-04 — `lumotia-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.
|
|
|
|
## Frontend
|
|
|
|
### KI-05 — Dual theme system: `settings.theme` and `preferences.theme` coexist
|
|
|
|
**Status:** Theme is stored twice. The legacy `settings.theme` ("Dark" / "Light" / "System", localStorage-only) is bound to two `SegmentedButton` controls in `SettingsPage.svelte`. The canonical `preferences.theme` ("dark" / "light" / "system", Tauri-persisted via `save_preferences`) is what the DOM and runtime actually consume. A migration `$effect` in `src/routes/+layout.svelte` (and the secondary `+layout@.svelte` files for `/preview`, `/viewer`, `/float`) syncs `settings.theme` → `preferences.theme` whenever the legacy value changes.
|
|
|
|
**Source:**
|
|
- [`src/lib/stores/page.svelte.ts:61`](src/lib/stores/page.svelte.ts#L61) (legacy default: `theme: "Dark"`)
|
|
- [`src/lib/stores/preferences.svelte.ts:30`](src/lib/stores/preferences.svelte.ts#L30) (canonical default: `theme: "dark"`)
|
|
- [`src/routes/+layout.svelte:61-68`](src/routes/+layout.svelte#L61) (migration `$effect`)
|
|
- [`src/lib/pages/SettingsPage.svelte:1118`](src/lib/pages/SettingsPage.svelte#L1118), [`:2360`](src/lib/pages/SettingsPage.svelte#L2360) (UI bindings still on the legacy field)
|
|
|
|
**Impact:** No user-facing bug; theme switching works. The cost is code complexity and a small race window where preference fan-out can lag behind a `settings.theme` change. The `$effect` is lightweight (string compare plus a debounced persist when the mapped value differs), not a hot-loop performance problem despite earlier framing.
|
|
|
|
**Resolution (deferred):** Switch the two `SettingsPage` bindings to `preferences.theme` with mapped options, retire the migration `$effect` in all four route layouts, drop `theme` from `SettingsState`, and add a one-shot localStorage migration that copies any historical `settings.theme` into `preferences` on first run after the cleanup. Touches ~5 files including the 2 484-LOC `SettingsPage.svelte`; deferred from the v0.1 polish pass to avoid a moderate-risk frontend change immediately before launch.
|
|
|
|
**Workaround:** N/A.
|
|
|
|
## Engine architecture (Phase A)
|
|
|
|
### KI-06 — `transcribe_file` and live-transcription commands not yet rewired through `Orchestrator`
|
|
|
|
**Status:** Phase A introduced the `TranscriptionProvider` async trait ([`crates/cloud-providers/src/provider.rs`](crates/cloud-providers/src/provider.rs)), `EngineRegistry` ([`crates/transcription/src/registry.rs`](crates/transcription/src/registry.rs)), and `Orchestrator` plus `LocalProviderAdapter` ([`crates/transcription/src/orchestrator.rs`](crates/transcription/src/orchestrator.rs)). The abstractions compile, are object-safe, and pass unit tests against a mock provider. The existing dictation path ([`src-tauri/src/commands/transcription.rs`](src-tauri/src/commands/transcription.rs)) still calls `LocalEngine::transcribe_sync` directly via `pick_engine`, not through the orchestrator. Live and meeting commands likewise route around the orchestrator.
|
|
|
|
**Source:** [`src-tauri/src/commands/transcription.rs:29`](src-tauri/src/commands/transcription.rs#L29) (`pick_engine`), [`src-tauri/src/commands/live.rs`](src-tauri/src/commands/live.rs), [`src-tauri/src/commands/meeting.rs`](src-tauri/src/commands/meeting.rs).
|
|
|
|
**Impact:** None at runtime. The orchestrator path is dormant until a follow-up commit migrates the call sites. Cloud providers (Phase G) cannot be exercised end-to-end until this rewire lands.
|
|
|
|
**Resolution (deferred):** Phase A.1 follow-up commit. Build an `EngineRegistry` at app boot (one `LocalProviderAdapter` per `LocalEngine`), inject `Arc<Orchestrator>` into `AppState`, replace `pick_engine` plus `engine.transcribe_sync` chunking-loop calls with `orchestrator.transcribe(audio, &profile)` per chunk. Keep the chunking strategy in the command layer (it is a strategy concern, not a dispatch concern). Tests should cover both paths against a mock provider before touching the real engines.
|
|
|
|
**Workaround:** N/A. Existing path works as before.
|
|
|
|
## 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.
|