Commit Graph

8 Commits

Author SHA1 Message Date
31e3f5a099 agent: lumotia — Phase B.3 unlink .part on ResumeUnsupported so retry can recover
Phase B.3 audit of commit 9f67ab2 (atomic model download + manifest —
Rev-1, Rev-5). Existing coverage is solid: the transcription-side
download_file has fixture tests for resume-and-verify, restart-on-200,
SHA-mismatch cleanup, 5xx rejection, Rev-1 preserve-existing-file, and
the Rev-5 manifest tmp+rename atomicity. The llm-side download_impl
has resume-and-verify and the Rev-1 preserve-existing-file regression.

One real residual found in crates/llm/src/model_manager.rs that the
original commit did not close.

When a stale .part exists (resume_from > 0) and the server returns a
200 full-body response to a Range request, download_impl returns
DownloadError::ResumeUnsupported without unlinking the .part. Every
subsequent download_model() call computes the same resume_from > 0,
sends the same Range request, gets the same 200, and fails the same
way — the download is wedged until the user manually invokes
delete_model(). That is itself a reversibility kill in the same
family as Rev-1: stale partial state stuck on disk, no automatic
recovery, the user has to discover an out-of-band command to escape.

The transcription-side download_file handles this case by treating
200-on-resume as a fresh-start (line 268: "Server ignored our Range
header — treat as fresh start"). The llm-side does not have an
analogous restart code path, but the simpler fix is sufficient: unlink
the .part before returning ResumeUnsupported. The next call sees
resume_from = 0, sends no Range header, the server returns 200, and
download_impl writes the new payload into a fresh .part and renames
atomically over dest. Single retry recovers.

Fix:
  * crates/llm/src/model_manager.rs:
      - download_impl: tokio::fs::remove_file(&tmp).await.ok() before
        returning ResumeUnsupported, with a comment that names this as
        a Phase B.3 audit residual and explains the wedge scenario.
      - New test resume_unsupported_unlinks_part_so_retry_starts_fresh
        — spins a server that ignores Range and returns 200, plants a
        sentinel .part, asserts ResumeUnsupported AND .part removed AND
        dest not written.

Verification:
  * cargo test -p lumotia-llm --lib model_manager
      → 5/5 pass including the new test.
  * cargo fmt --check → clean.
  * cargo clippy -p lumotia-llm --all-targets -- -D warnings → clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 19:23:24 +01:00
9f67ab2d86 agent: code-atomiser-fix — atomic model download + manifest (Rev-1, Rev-5)
Two reversibility kills in the model-download path both followed the
same pattern: SHA mismatch on an existing file triggered
`remove_file(&dest)` BEFORE the network round-trip. A network blip /
power loss between the unlink and the eventual `rename(.part, dest)`
left users with neither the old (corrupt-but-readable) model nor a
fresh one — 1.5-20 GB redownload from scratch with no fallback.

Rev-1 (crates/llm/src/model_manager.rs):
  - Extract the existing-file decision into `download_to`, drop the
    pre-emptive unlink. `download_impl` already writes via `.part`
    and atomically renames; the rename overwrites on success and
    leaves dest untouched on failure.
  - Regression test `download_failure_preserves_existing_file` plants
    a sentinel "OLD" file at dest, points at a 500-returning server,
    and asserts dest still exists with original contents after the
    failed download.

Rev-5 (crates/transcription/src/model_manager.rs):
  - Drop the pre-emptive unlink in the outer `download()` SHA-mismatch
    branch. Same atomic rename via `download_file`.
  - Make `write_verified_manifest` atomic: write to `.tmp`, fsync,
    rename. Previous direct `fs::write` truncates-then-writes, so a
    crash mid-write left an empty/torn manifest and triggered a full
    GB-sized redownload on next boot.
  - `download_file_failure_preserves_existing_dest_file` and
    `manifest_write_is_atomic` regression tests added.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 15:21:01 +01:00
26c7307607 agent: lumotia-rebrand — docs, scripts, root config, residuals
Some checks failed
check / cargo check (macos-latest) (push) Has been cancelled
check / cargo check (ubuntu-22.04) (push) Has been cancelled
check / cargo check (windows-latest) (push) Has been cancelled
check / svelte build + lint (push) Has been cancelled
Phase 9 of the rebrand cascade. Sweep covers everything the Phase 8
frontend pass deliberately skipped: docs/, root markdown, scripts,
Cargo.toml descriptions, code comments that survived earlier
word-boundary sed, plus a handful of identifiers caught on the final
verify pass.

transcription-app changes:
- README.md, HANDOVER.md, KNOWN-ISSUES.md, run.sh — magnotia/Magnotia
  -> lumotia/Lumotia.
- docs/ — sweep across all subdirs except docs/handovers/ (preserved
  as immutable audit trail). Includes architecture-map references
  to magnotia_core::*, magnotia_storage::*, etc. now pointing at
  lumotia_*; dev-setup.md tracing output examples (lumotia_startup
  target); brief/ + superpowers/ + issues/ + whisper-ecosystem/ +
  audit/.
- Cargo.toml descriptions on 9 crates (core, audio, cloud-providers,
  hotkey, llm, mcp, plus referenced others).
- crates/core/src/{error,hardware,recommendation,paths}.rs +
  crates/audio/src/wav.rs + crates/llm/src/model_manager.rs +
  crates/cloud-providers/src/keystore.rs + crates/mcp/src/lib.rs —
  doc comments and a model-manager user-agent string.
- Caught on final pass: BroadcastChannel("magnotia_task_sync") -> ...
  ("lumotia_task_sync"); magnotia_locale i18n localStorage key
  renamed + migration shim added; CSS keyframe names
  magnotiaPulse / magnotiaBar / magnotiaFade renamed in the design-
  system kit; magnotia_viewer_item / magnotia_viewer_mode handoff
  keys renamed in HistoryPage + viewer/+page.svelte; src/assets/
  wordmark.svg text.
- src-tauri/src/lib.rs comment cleanup ("magnotia era" was sed'd
  to "lumotia era" earlier — restored).

Preserved (intentional):
- crates/core/src/paths.rs — keeps "magnotia" / "Magnotia" / ".magnotia"
  legacy detection strings in legacy_and_target_paths() so the
  migration shim can still find user data from the magnotia era.
- src/lib/stores/{page,focusTimer}.svelte.ts + src/lib/i18n/index.ts
  — migration call sites reference the legacy magnotia keys
  deliberately.
- docs/handovers/ — historical audit trail.

cargo build --workspace passes. npm run check: 0 errors / 0 warnings
(3958 files). cargo test --workspace: 339 pass / 0 fail.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 12:38:03 +01:00
089349d966 agent: lumotia-rebrand — rust workspace crates magnotia-* -> lumotia-*
Some checks failed
check / cargo check (macos-latest) (push) Has been cancelled
check / cargo check (ubuntu-22.04) (push) Has been cancelled
check / cargo check (windows-latest) (push) Has been cancelled
check / svelte build + lint (push) Has been cancelled
Phase 2 of the rebrand cascade. Renames all 9 workspace crates from
magnotia-* to lumotia-* plus the src-tauri binary crate name:

- magnotia-ai-formatting   -> lumotia-ai-formatting
- magnotia-audio           -> lumotia-audio
- magnotia-cloud-providers -> lumotia-cloud-providers
- magnotia-core            -> lumotia-core
- magnotia-hotkey          -> lumotia-hotkey
- magnotia-llm             -> lumotia-llm
- magnotia-mcp             -> lumotia-mcp
- magnotia-storage         -> lumotia-storage
- magnotia-transcription   -> lumotia-transcription
- magnotia                 -> lumotia (src-tauri binary)
- magnotia_lib             -> lumotia_lib (src-tauri lib target)

Crate directories (crates/audio/ etc.) stay as-is; only the Cargo.toml
[package] name field changes plus all consumer module imports
(magnotia_core -> lumotia_core, etc.).

Remaining magnotia_* references at this point are intentional and
scoped to later phases: tracing targets (Phase 4), DB setting keys
magnotia_preferences/magnotia_history (Phase 5).

cargo build --workspace passes. cargo test --workspace: 330 pass, 0 fail.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 08:48:09 +01:00
699cb7e08e feat(llm): bump model registry to Qwen3.5 + Qwen3.6 family (4 tiers)
Replaces the three older Qwen3 variants with a four-tier ladder spanning
a wider hardware range:

- Qwen3_5_2B_Q4   (Minimal, 8 GB RAM, ~1.3 GB download)
- Qwen3_5_4B_Q4   (Standard, 16 GB RAM / 6 GB VRAM, ~2.7 GB) — DEFAULT
- Qwen3_5_9B_Q4   (High, 32 GB RAM / 12 GB VRAM, ~5.7 GB)
- Qwen3_6_27B_Q4  (Maximum, 64 GB RAM / 24 GB VRAM, ~17 GB)

All four GGUFs sourced from unsloth's HF org with pinned commit SHAs.
Sizes and SHA256 hashes verified against the live X-Linked-Etag /
X-Linked-Size headers on the LFS CDN. Q4_K_M quantisation throughout
(common sweet-spot for cleanup + task extraction).

recommend_tier rewritten to span four bands; default_tier moves from
the old 4B-Instruct-2507 to Qwen3.5 4B. The 27B Maximum tier honestly
needs 64 GB RAM to run without partial offload — surfaced in the
description string so the Settings UI can warn realistically.

In-tree smoke tests (smoke.rs, content_tags_smoke.rs) updated to
reference the new smallest tier so a developer's MAGNOTIA_LLM_TEST_MODEL
points at the cheapest GGUF to download. Crate description in
crates/llm/Cargo.toml refreshed to mention the new family.

NOTE (out of scope; not fixed): the size_bytes / sha256 / hf_url
methods could collapse into a single LlmModelMetadata table to remove
four parallel match arms. Layer 2 cleanup, separate session.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 09:57:21 +01:00
Claude
89c63891fa chore: rebrand from Kon/Corbie to Magnotia
Replace all instances of the legacy product names "Kon" and "Corbie" with
"Magnotia" across user-facing copy, code identifiers, package names, bundle
ids, file paths, and documentation. Preserves the unrelated "konsole" (KDE
terminal) reference and the parent CORBEL company name.

- Renames 10 Rust crates (kon-* → magnotia-*) and the tauri binary
- Updates package.json, tauri.conf.json (productName + identifier)
- Renames CSS classes (kon-rh-* → magnotia-rh-*) and animations
- Renames brand and roadmap docs
- Regenerates Cargo.lock and package-lock.json

Verified: svelte-check passes; pure-rust crates compile under new names.
2026-04-30 13:06:55 +00:00
b333c6229e chore(hardening): tighten security and footprint defaults 2026-04-24 19:03:57 +01:00
d1eb56fac9 feat(llm): wire Phase 3 local LLM runtime via llama-cpp-2
kon-llm now owns a real LlamaBackend + LlamaModel, with three Qwen3 tiers
(1.7B Q4, 4B-Instruct-2507 Q4, 14B Q5) selectable per hardware. Downloads
are resumable with SHA-256 verification and stored under ~/.kon/models/llm.

Engine exposes three high-level surfaces — all greedy/temp-0, GBNF-constrained
where output shape matters:
- cleanup_text (prompt-injection-hardened system prompt; profile terms
  appended as "preserve these spellings" suffix)
- decompose_task (3–7 micro-steps, constrained JSON array)
- extract_tasks (optional-array; empty when no explicit commitments)

post_process_segments now takes an Option<&LlmEngine> and, when loaded and
format_mode != Raw, joins segments → cleanup → replaces segments with the
cleaned text (first segment span). Rule-based path still runs first; LLM
errors log and keep rule-based output.

Tauri commands: recommend_llm_tier, check_llm_model, download_llm_model,
load_llm_model, unload_llm_model, delete_llm_model, get_llm_status,
cleanup_transcript_text_cmd, extract_tasks_from_transcript_cmd,
decompose_and_store (LLM-backed subtasks).

Settings: AI tier toggle (off / cleanup / tasks), model picker with
downloaded/loaded status, download progress events via
kon:llm-download-progress.

Dictation: ensureLlmModelLoaded on mount, cleanupTranscriptIfEnabled after
stop when tier != off and format_mode != Raw, LLM task extraction when
tier=tasks (regex fallback on failure).

Interim: both llama-cpp-sys-2 and whisper-rs-sys statically link their own
ggml, so src-tauri/build.rs emits -Wl,--allow-multiple-definition on Linux.
Replace with a system-ggml shared-lib setup as a follow-up.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 07:31:51 +01:00