2f11f493c507ee970b48241321f4a44e97fdbce4
18 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
| 3770815fbf |
agent: lumotia — v0.1 release-completion run
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. |
|||
| 43d319fd5a |
agent: lumotia — Phase A.1+A.2 rebrand migration tests + copy_dir_recursive hardening
Phase A of dogfood verification for the Magnotia -> Lumotia rebrand
cascade. The existing in-crate unit tests prove the migration copies
bytes correctly; this commit closes the gaps an atomiser-grade review
would flag.
Phase A.1 — end-to-end integration test (crates/storage/tests/legacy_db_migration.rs):
Seeds a real on-disk magnotia.db via lumotia_storage::init (which runs
every schema migration head-to-tail), inserts a transcript via the
public API, drops the pool, runs migrate_legacy_data_dir_with_pairs,
then re-opens the migrated lumotia.db and asserts the transcript is
queryable. Three scenarios covered:
1. Legacy-only -> migrate -> reopen -> row survives. Also verifies a
non-DB companion file is carried along by the directory rename.
2. Idempotency: first boot migrates, user writes new data, second
boot is a no-op and BOTH rows survive.
3. Both-paths-present: refuses to merge, target's empty DB is
preserved, legacy retained on disk as a backup.
Wires the test surface by renaming the previously-private
migrate_legacy_data_dir_inner to pub migrate_legacy_data_dir_with_pairs
(mirroring migrate_tauri_app_data_dir_with_paths in the sibling
tauri_app_data_migration module).
Phase A.2a — copy_dir_recursive hardening (crates/core/src/paths.rs):
Pre-existing footgun: the fall-through branch called std::fs::copy()
on any DirEntry that was not a symlink or a directory. On Unix that
includes FIFOs, sockets, and char/block device nodes. Opening a FIFO
for read with no writer attached blocks forever — a stale debug FIFO
in the user's ~/.magnotia tree would silently hang first launch.
The branch now explicitly distinguishes is_file() (real regular file
-> copy) from anything else (-> Err with ErrorKind::Unsupported,
naming the offending path). Migration becomes re-runnable once the
user cleans up the offending node. Same-filesystem rename via
std::fs::rename is atomic and unaffected; only the EXDEV fallback path
touches the new guard.
Phase A.2b — three adversarial probes (crates/core/src/paths.rs tests):
- FIFO inside the legacy tree: copy_dir_recursive must return an
Unsupported error WITHOUT hanging. Test bounded by a 5s wall clock
+ a worker thread so a regression to the old fall-through would
surface as a panic, not a stalled CI job.
- Unreadable file (mode 0000): copy_dir_recursive must surface
PermissionDenied, not silently skip. Skips its core assertion under
euid 0 (root bypasses DAC permissions, would mask the regression).
- Dangling symlink (target nonexistent): symlink is recreated at
destination with link target preserved verbatim; the migration
does NOT try to dereference and does NOT abort the rest of the copy.
Verification:
- cargo fmt --check: clean
- cargo clippy --workspace --all-targets -- -D warnings: clean
- cargo test --workspace: 409 passed, 0 failed (up from 405 pre-commit;
3 storage integration tests + 3 paths adversarial + 1 net carry-over)
|
|||
| afbd33d33e |
agent: code-atomiser-fix — test_llm_model respects caller GPU preference (Race-8)
Add an Option<bool> use_gpu parameter to test_llm_model with the same default-true semantics as load_llm_model. Hard-coding true triggered an engine tear-down/rebuild when a parallel load_llm_model(use_gpu=false) was in flight (LlmEngine::load_model triples on id+path+use_gpu) and silently flipped the user's GPU mode underneath the test. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
|||
| 089349d966 |
agent: lumotia-rebrand — rust workspace crates magnotia-* -> lumotia-*
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> |
|||
| 52565ea8b8 |
agent: area A commit 1 — typed magnotia_storage::Error + boundary
Commit 1 of 2 for engine-slop residuals Area A.
Adds a typed `magnotia_storage::Error` enum and rewires every error
construction site in the storage crate to use it. The crate boundary
into `magnotia_core::error::MagnotiaError` is handled by a
`From<storage::Error> for MagnotiaError` impl that lives inside the
storage crate (not in core) to avoid a `core -> storage` dependency
cycle. The old `MagnotiaError::StorageError(String)` variant is kept
in this commit as an unused placeholder; commit 2 deletes it.
New types in crates/storage/src/error.rs:
- pub enum Error { DatabaseOpen, Migration, Query, NotFound,
InvalidReference, Filesystem } with #[derive(thiserror::Error)]
- pub enum OpenOp { Connect, ReadOnlyConnect, ForeignKeysPragma }
- pub enum MigrationStep { SchemaVersionTableCreate, SchemaVersionQuery,
TxBegin, Apply, RecordVersion, Commit }
- pub enum Entity { Transcript, Task, Profile, ImplementationRule,
Feedback } — seeded only with entities that have a real
NotFound/InvalidReference case in the codebase
- pub type Result<T> = std::result::Result<T, Error>
- impl Error { pub fn kind() -> StorageKind, pub fn
operation_label() -> Cow<'static, str> }
- impl From<Error> for MagnotiaError
New types in crates/core/src/error.rs:
- MagnotiaError::Storage { kind: StorageKind, operation: String,
detail: String } with #[error("{detail}")] so the boundary doesn't
double-prefix Display output
- pub enum StorageKind { DatabaseOpen, Migration, Query, NotFound,
InvalidReference, Filesystem } #[derive(Serialize)]
#[serde(rename_all = "snake_case")] for future Area E
Storage crate dependency added: thiserror = "1"
Migration scope:
- migrations.rs: 6 sites → Error::Migration with structured step + version
- database.rs: 72 sites broken down as:
* 3 → Error::DatabaseOpen (init / readonly / pragma)
* 1 → Error::Filesystem (init's create_dir_all with path context)
* ~58 → Error::Query with operation labels matching the prior message
stem in snake_case; transaction sub-steps use dotted labels
("complete_subtask_and_check_parent.commit_transaction" etc.)
so transaction internals are not collapsed
* 5 → Error::NotFound (transcript / task×2 / implementation_rule×2)
* 5 → Error::InvalidReference (insert_transcript unknown profile;
Default profile rename/delete invariants ×3; feedback rating
value validation)
Survey ambiguities resolved per the locked answers:
- Q1 (schema_version_query): Migration step, not Query
- Q2 (transaction sub-steps): preserved granularity with dotted operation
labels; no collapsing
- Q3 (Entity cardinality): seeded with the 3 from the survey + 2 more
discovered during migration (ImplementationRule, Feedback), per
"add when an actual case needs it"
- Q4 (operation label type): Cow<'static, str>
- Q5 (Serialize): storage::Error is not serializable; flattens only at
the MagnotiaError boundary
- Q6 (re-exports): pub use error::{Entity, Error, MigrationStep, OpenOp,
Result} in storage::lib.rs; StorageKind belongs to magnotia_core
Two scope-discovered additions beyond the original 5 variants:
- Error::Filesystem { path, source } variant + matching StorageKind —
required because init() now returns storage::Result<SqlitePool> and
the create_dir_all call needs a typed path; doing this via
From<io::Error> for storage::Error would have lost the path so it's
explicit
- Entity::ImplementationRule and Entity::Feedback — two NotFound /
InvalidReference sites the original survey missed in the rule-CRUD
and feedback-validation areas
Verification:
- cargo fmt --all
- cargo check --workspace --all-targets — clean
- cargo test -p magnotia-storage — 60 passed, 0 failed
- cargo test --workspace — all green, ~330 tests
- rg 'StorageError\(' crates/ src-tauri/src/ — only hit is the variant
declaration in core that commit 2 will delete
- rg 'Other\(String' crates/storage/src/ — zero
- rg 'format!\("[A-Z].* failed' crates/storage/src/ — zero
Commit 2 will delete MagnotiaError::StorageError(String) once this is
in. Pre-existing working-tree churn in crates/llm/, src/lib/pages/,
src/lib/utils/saveMarkdown.ts and the untracked phase10a dogfood notes
deliberately left unstaged.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|||
| 48c483894b |
agent: finish tracing migration for hotkey logs
Follow-up to |
|||
| 184214b60a |
agent: engine slop residuals B — eprintln → tracing sweep
Replaces 22 production eprintln! sites with structured tracing events across 8 files. Closes Area B of the post-prognosis residuals plan (docs/superpowers/plans/2026-05-12-engine-slop-residuals.md). Files touched (22 sites): - crates/hotkey/src/linux.rs (2) — hotplug watcher degraded-mode warnings - crates/ai-formatting/src/pipeline.rs (1) — LLM cleanup fallback warning - src-tauri/src/commands/transcription.rs (1) — chunking dispatch info - src-tauri/src/commands/diagnostics.rs (1) — crashes-dir setup warning - src-tauri/src/commands/tasks.rs (1) — malformed feedback row warning - src-tauri/src/commands/power.rs (3) — App Nap acquire/release/fail - src-tauri/src/commands/models.rs (5) — Whisper warmup lifecycle - src-tauri/src/commands/live.rs (8) — session start, chunk dispatch, per-chunk delivery, inference errors, worker disconnects, listener loss, status-channel cascade Levels: error for unrecoverable failures (inference disconnect, panic, status cascade), warn for recoverable degradation (LLM fallback, malformed rows, App Nap fail, hotplug watcher fail), info for lifecycle (session start, chunk processed, App Nap acquire/release, warmup complete, chunking dispatch), debug for per-chunk noise (speech-gate skip, chunk dispatch). Two new dependencies and two new filter targets: - tracing = "0.1" added to crates/hotkey and crates/ai-formatting - Default EnvFilter in src-tauri/src/lib.rs::init_tracing extended with magnotia_hotkey=info,magnotia_ai_formatting=info so the new targets emit at the default level Out of scope (intentional, left as-is): - crates/mcp/src/main.rs — CLI binary, stderr is the log contract (module docstring) so the JSON-RPC stdout stream stays clean - crates/*/tests/*.rs and crates/core/examples/tuning_log_demo.rs — test/example diagnostic output relies on --nocapture stdio semantics Discovery during sweep (not fixed — separate follow-up): hotkey crate has 6 existing log:: calls (log::error/warn/info/debug) but the workspace builds tracing-subscriber without the tracing-log feature, so those events are currently silent. Worth a follow-up to either add the tracing-log bridge or migrate hotkey's existing log:: calls to tracing::. Verification: - cargo fmt --all - cargo check --workspace --all-targets — clean - cargo test --workspace — 330+ tests, zero failures - rg eprintln! src-tauri/src/commands/ crates/hotkey/src/ crates/ai-formatting/src/ — zero hits Pre-existing working-tree churn in crates/llm/, src/lib/pages/, src/lib/utils/saveMarkdown.ts and the untracked phase10a dogfood notes deliberately left unstaged per Jake's instruction. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
|||
| db654deecc |
agent: engine slop pass — DSP, typed errors, regex parsing, tracing, audit fixes
External code review on 2026-05-12 rated the codebase 4/10 across audio DSP, error typing, JS injection, env-var safety, ALSA parsing, and async logging. This commit lands the prognosis-level fixes plus three audit follow-ups. Audio/DSP: - StreamingResampler/rubato confirmed in the live capture path - regression test at 12 kHz (rms < 0.01, ~40 dB) catches naive decimation - near-Nyquist test at 9 kHz (rms < 0.05, ~26 dB) exercises transition band Core errors: - Other(String) removed; ProviderNotRegistered introduced - Io variant restructured as struct with kind/message/raw_os_error - FileNotFound display quotes paths - Configuration variant removed (unused) Core types: - ModelId, EngineName backed by Cow<'static, str>; const borrowed ctor - Megabytes::from_gb takes u64 (was f64) - AudioSamples::sample_rate is NonZeroU32; zero-rate defensive branch removed Capture: - /proc/asound/cards parsing rewritten as anchored regex (OnceLock) - regression test covers product names with embedded colons - monitor_pattern_detection test restored alongside the regex test - DEAD_SILENCE_FLOOR promoted to module-level with rationale - DEVICE_VALIDATION_MS, SILENCE_RMS_FLOOR documented with field-observation rationale - RMS validation loop made idiomatic - eprintln! migrated to tracing with structured fields and targets Tauri startup: - unsafe std::env::set_var removed; ensure_x11_on_wayland renamed to warn_if_x11_env_unset_on_wayland (launcher/wrapper owns env-var contract) - DB init + log prune + preferences load collapsed to one block_on - build_preferences_script rewrites JS injection from JSON.parse string to direct object literal plus malformed-JSON guard and unit tests - WebKitGTK microphone auto-grant logs warning at startup - tracing subscriber initialised at top of run() (warn,magnotia=info,... on stderr; honors RUST_LOG); previously eprintln→tracing migration was silent because no subscriber existed Filename counter: - RECORDING_COUNTER uses SeqCst Tests: cargo test --workspace --lib green (322 passed, 0 failed across 10 crates). Three independent audits (original cleanup → Wren → fresh Codex subagent) concur on no critical findings. Deferred to docs/superpowers/plans/2026-05-12-engine-slop-residuals.md: storage-layer typed errors, remaining eprintln→tracing sweep, capture actor-model refactor, property-based DSP testing, frontend/backend error boundary cleanup. |
|||
| 6bc8acccce |
feat(transcription): Phase A — engine protocol + registry + orchestrator (clean-room)
Introduces the architectural spine for the Wyrdnote engine layer per the spec at outputs/wyrdnote/2026-05-10-engine-architecture-spec.md in the CORBEL-Main workspace, Codex-reviewed 2026/05/10. Clean-room derivative of VoiceInk's TranscriptionService / TranscriptionServiceRegistry / TranscriptionPipeline shape. Built from the architectural pattern only; no GPL-3.0 code, comments, or identifiers lifted. Wyrdnote names, control flow, and trait signatures are original. What this lands: crates/cloud-providers/src/provider.rs (new, 184 lines) TranscriptionProvider async trait. Object-safe via async_trait so Arc<dyn TranscriptionProvider> is the canonical shape. Lives in cloud-providers (not transcription) per D7 so an OEM licensee implementing the trait depends only on this crate plus magnotia-core (no transcription internals leaked through the trait surface). Surrounding types: ProviderId (lower-kebab-case), ProviderKind, NetworkRequirement, CostClass, ProviderCapabilities, EngineProfile, ProviderTranscript. Compile-time object-safety witness in tests. crates/cloud-providers/Cargo.toml (modified) Adds async-trait + serde dependencies. crates/cloud-providers/src/lib.rs (modified) Re-exports the provider surface. crates/transcription/src/registry.rs (new, 183 lines) EngineRegistry: catalogue of providers keyed by ProviderId. Push-style registration, default-provider id captured at construction. Read-only after boot. Full unit-test coverage: empty default, register/get round-trip, default-resolves-after-registration, re-register replaces, ids enumeration. crates/transcription/src/orchestrator.rs (new, 286 lines) LocalProviderAdapter wraps Arc<LocalEngine>, presents async TranscriptionProvider upward via tokio::task::spawn_blocking. Per D7 the adapter lives in the orchestrator, NOT as impl TranscriptionProvider for LocalEngine — this keeps the dependency edge one-directional and avoids leaking async-runtime requirements onto the synchronous Transcriber trait. Orchestrator: single transcribe() entry point; resolves a provider from the registry, derives TranscriptionOptions from the EngineProfile, dispatches. Returns a clear error when an unregistered provider is named. Unit tests use a mock CannedProvider to validate dispatch, error handling, and option routing without booting a real model. crates/transcription/Cargo.toml (modified) Depends on magnotia-cloud-providers + async-trait. Dev-dep tokio gains macros + rt-multi-thread features for #[tokio::test]. crates/transcription/src/lib.rs (modified) Exports Orchestrator, EngineRegistry, LocalProviderAdapter, and re-exports the provider trait surface so downstream crates depend only on magnotia-transcription for both local engines and the trait. KNOWN-ISSUES.md (modified) Adds KI-06: existing dictation, live, and meeting commands still call LocalEngine::transcribe_sync directly via pick_engine. The orchestrator path is dormant until a Phase A.1 follow-up commit migrates the call sites. Cloud providers (Phase G) cannot be exercised end-to-end until the rewire lands. Phasing rationale: this commit lands the abstractions cleanly with full test coverage; the rewire is a separate diff so the chunking + post-processing logic in transcribe_file moves without inflating this commit beyond review fidelity. Test results: 9 new tests pass (orchestrator: dispatches, errors-on- unregistered, routes-initial-prompt, object-safe; registry: empty-default, round-trip, default-resolves, re-register, ids-list). Pre-existing 59 transcription tests + 5 cloud-providers tests still green. cargo check --workspace clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
|||
|
|
3c47000ea9 |
chore(core): add tuning_log_demo example for live heuristic validation
Run with: cargo run -p magnotia-core --example tuning_log_demo Initialises a tracing-subscriber fmt layer so the inference_thread_count INFO event is rendered to stderr. Exercises all 8 (workload, gpu_offloaded) combos under three power scenarios: AC override, battery override, and the real sysfs probe. Used to validate the heuristic on 2026-05-09 against the spec's 6c12t truth table — all 6 rows match. Adds tracing-subscriber as a [dev-dependencies] for the example. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
e715da3b54 |
feat(transcription): whisper threads use Workload::Whisper + GPU detection
Wires the whisper backend through the new tuning helper. gpu_offloaded
combines a compile-time feature check (whisper-vulkan, in default
features) with a runtime libvulkan probe via the hardware module. If
libvulkan1 is missing on Linux, whisper-rs's vulkan backend silently
falls back to CPU, so we should not reduce threads in that case.
The old magnotia_core::constants::inference_thread_count import is
replaced by tuning::{inference_thread_count, Workload}. The constants
module's helper is removed in Task 6.1 once the LLM call site has
also migrated.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
1f3496e4ed |
feat(core): add PowerState skeleton in new power module
Introduces crates/core/src/power.rs with the PowerState enum (OnAc / OnBattery / Unknown) and a unit test confirming the three variants are distinct. Registers the module in lib.rs and adds tempfile = "3" to dev-dependencies for use in later tasks. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
4cb954ece4 |
perf: route whisper + llm n_threads through physical-core helper
Both inference call sites previously called `num_cpus::get()` (logical
thread count). Established whisper.cpp / llama.cpp guidance is that
SMT siblings contend for shared FPU resources during heavy F16/F32
matmul, so going past physical core count anti-scales. Empirical
sweep on Whisper Tiny / 11s JFK clip / Ryzen 5 4650U (6c12t):
n_threads | xc_time | RTF | speedup_vs_1
----------|---------|--------|-------------
1 | 0.33s | 0.030 | 1.00x
2 | 0.33s | 0.030 | 1.00x
4 | 0.30s | 0.028 | 1.09x
6 | 0.32s | 0.029 | 1.04x
8 | 0.31s | 0.028 | 1.06x
12 | 0.32s | 0.029 | 1.03x
Tiny doesn't scale (work dominated by overhead) but the larger
Whisper variants and Qwen LLMs do. Sources: whisper.cpp #200, #1033,
#1252, #403; llama.cpp #3167, #572.
Changes:
- crates/core/src/constants.rs:
* MIN_INFERENCE_THREADS lowered 4 → 2 (research-derived floor)
* MAX_INFERENCE_THREADS = 8 added (research-derived ceiling)
* inference_thread_count() rewritten:
- reads MAGNOTIA_INFERENCE_THREADS env var (override)
- num_cpus::get_physical() with available_parallelism fallback
- clamped to [MIN_INFERENCE_THREADS, MAX_INFERENCE_THREADS]
- crates/core/Cargo.toml: + num_cpus = "1"
- crates/transcription/src/whisper_rs_backend.rs: call site uses helper.
- crates/llm/src/lib.rs: call site uses helper.
- crates/transcription/Cargo.toml: drop num_cpus from [features] +
[dependencies] (production no longer needs it). Move to
[dev-dependencies] for tests/thread_sweep.rs only.
- crates/llm/Cargo.toml: drop num_cpus = "1" (no longer used directly).
Per-machine maps (after this patch):
Ryzen 5 4650U 6c12t → 6
big-iron 12c24t → 8 (clamp; users can override)
cheap 2c2t laptop → 2
1c container/VM → 2
Adds crates/transcription/tests/thread_sweep.rs — env-gated like
jfk_bench, prints the table above against any model + WAV. Useful for
re-baselining on new hardware or when tuning the clamp values.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
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. |
||
| 489c066a70 |
feat(phase9): migration v14 + storage and Tauri command extension for llm_tags
Adds llm_tags TEXT NOT NULL DEFAULT '' to the transcripts table via new migration v14. SELECT statements + TranscriptRow + transcript_row_from now carry the column. update_transcript_meta gains a sixth Option for llm_tags following the existing COALESCE pattern; an #[allow(too_many_arguments)] keeps clippy happy without inverting the signature into a struct that would just shift the indirection. The Tauri-side TranscriptDto + UpdateTranscriptMetaRequest + the update_transcript_meta_cmd command pass llm_tags through unchanged. Pre-existing manualTags persistence path now has a sibling for llmTags ready for the frontend to call. Phase 8 brittle test fix included: list_recent_completions_uses_local_day_boundary was anchoring its "-2 days" UTC offset against the local-day spine, which drifted across UTC midnight. Anchored to the local date directly so it matches the spine regardless of clock. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
|||
| 512c9f7a19 |
chore(gamification): update Cargo.lock for kon-storage serde dep
Downstream effect of the Task 4 commit (
|
|||
| eebea8cb9a |
feat(nudges): Phase 6 — Margot soft-touch nudges via frontend nudge bus
Frontend-owned nudge bus that consumes in-app signals Corbie already produces, applies suppression, and fans out to OS notification + an optional TTS read-aloud. OS-wide keyboard/window activity detection stays deferred per the revised roadmap — the plan before rewrite would have been brittle on Wayland, permission-heavy on macOS, and low-quality everywhere. Triggers (v1, all in-app signals): - inactivity_with_active_timer — timer running, window blurred ≥ 90 s, at least 60 s into the timer. - pending_morning_triage — ritual enabled, past 10:00 local, last shown ≠ today. Polls every 5 min while focused. - micro_step_idle — micro-step decomposition created, no child step or parent task completed within 15 min. Suppression: - Respects nudgesEnabled + nudgesMuted. - No nudge while the app has focus (document.hasFocus). - Hard cap 3 per rolling hour. - Permission requested via @tauri-apps/plugin-notification on first delivery; denial is silently respected. Rust side: - tauri-plugin-notification registered + ACL entries on the main- window capability only (secondary windows can't fire nudges). - commands::nudges::deliver_nudge — thin wrapper, security-guarded via ensure_main_window, delegates to the plugin. No DB writes — the roadmap's nudges-audit table is deferred until a concrete need emerges. Frontend glue: - nudgeBus.svelte.ts — subscribes to window events, applies suppression, calls deliver_nudge (+ tts_speak when speakAloud is on). - kon:task-completed now dispatched on complete_task_cmd success. - kon:microstep-generated + kon:step-completed dispatched from MicroSteps so the idle trigger can clear itself on any engagement. - kon:focus-timer-cancelled added to focusTimer so the bus can reset its inactivity state on cancel, not only on natural completion. - nudgeBus started from +layout.svelte onMount, stopped on destroy. Settings: - New "Nudges" section with three toggles: Enable nudges, Mute for now (separate so a hard mute doesn't lose preferences), Speak nudges aloud (reuses Phase 4 TTS). - All default OFF. No first-run prompt — nudges are a Settings-found feature rather than a walkthrough step. Out of scope per the revised Phase 6 spec: OS-wide keyboard/window hooks, biometric signals, custom trigger editor (Phase 7), notification sound (platform variance too high for Layer-1 — revisit in Phase 9 polish with a bundled .wav). Gates: fmt clean, clippy -D warnings clean, cargo test 262/0 (4 existing + 262 current), npm run check 0/0, npm run build green. |
|||
| b333c6229e | chore(hardening): tighten security and footprint defaults |