10 Commits

Author SHA1 Message Date
f03f8a01b0 v0.2 Phase 8: full release gate — all checks green
cargo fmt --check                                         ✓
  cargo clippy --workspace --all-targets -- -D warnings     ✓
  cargo test --workspace                                    ✓
  cargo nextest run --workspace                             ✓ 435/435
  npm run check                                             ✓ 0/0/5704 files
  npm test                                                  ✓ 13/13 (2 files)
  npm run test:browser                                      ✓ 3/3 in Chromium
  npm run test:e2e                                          ✓ 16/16 × 2 viewports
  npm run analyze                                           ✓ reports/bundle-stats.html (1.7 MB)
  scripts/dogfood-rebrand-drill.sh                          ✓ 8/8 (sandbox)
  npm run guard:no-skeleton                                 ✓ clean

Two small Phase 8 corrections landed alongside the gate:

vite.config.js: the jsdom suite was picking up
`src/lib/ui/*.browser.test.ts`, which only works under the
@vitest/browser-playwright provider. Added the browser-suffix glob to
the jsdom suite's exclude list so the two runners stop double-running
the same files.

playwright.config.ts: bumped the global `expect.timeout` to 15 s. The
cold first-compile of the Vite SPA tree was exceeding Playwright's
default 5 s `toBeVisible` timeout on the 900x700 project on dogfood
runs. The 1440x900 project (which runs second after a warm cache)
never hit it.

Phase 8 closes Phase-7 page migrations. Branch is ready for the
finishing-a-development-branch handoff.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 09:07:10 +01:00
ba851680ce v0.2 Phase 7.8 / 7.9 / 7.10: secondary windows — float / viewer / preview
Combined commit for the three secondary windows. Each +layout@.svelte
was already migrated in Phase 3 KI-05 (the legacy theme-sync $effect
was deleted). The +page.svelte content for each window is explicitly
bespoke per docs/release/v0.2-frontend-overhaul.md §6.3:

  /float    — Lumotia-To-do panel: list pills, drag-and-drop between
              lists, context menus, pin-on-top, custom titlebar drag
              region. No Card/EmptyState/Toggle wrappers apply.

  /viewer   — Transcript viewer with audio player, segment scrubbing,
              speaker labels. Bionic-reading action + per-region
              accessibility typography are load-bearing. No wrappers.

  /preview  — Wayland-hardened transcription preview overlay.
              WindowTypeHint::Utility, never steals focus, hidden
              from Alt+Tab. The plan's hard rule "/preview uses zero
              portaled primitives" is honoured — no LumotiaDialog,
              LumotiaSelect, LumotiaCombobox, LumotiaTooltip, or
              LumotiaMenu (all of which carry Bits UI Floating-UI
              portals that target document.body).

Phase 7 closes here. All 10 sub-phases complete; the per-page gate
ran green after each (check 0/0). Full Phase 8 gate fires next.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 09:02:41 +01:00
a9733544c0 v0.2 Phase 6: shell split — AppRuntime / AppChrome / AppOverlays
src/routes/+layout.svelte was 537 LOC of mixed runtime, chrome and
overlay concerns. Split into three single-purpose shells under
src/lib/shell/, with +layout.svelte reduced to ~28 LOC of pure
composition.

AppRuntime (no DOM beyond <svelte:window>):
  - Global hotkey dual backend (evdev / tauri-plugin-global-shortcut)
  - 120ms hotkey debounce (sacred behaviour §5 #2)
  - PREFERENCES_CHANGED_EVENT listener (sacred §5 #4)
  - KI-05 one-shot legacy-theme migration
  - Sidebar hotkeys: [ toggle, Ctrl+K, Ctrl+, (sacred §5 #10)
  - Wind-down tray listener
  - Meeting auto-capture poller
  - Global frontend error capture
  - Nudge bus + implementation intentions lifecycle
  - Font-size CSS var $effect
  - Window resize → sidebar auto-collapse
  - Onboarding/first-run check + update check + LLM status warm-up

AppChrome (the visual shell):
  - Titlebar (OS-aware via customChrome helper)
  - Sidebar (recording-state-aware — sacred §5 #1 stays in
    Sidebar.svelte verbatim)
  - Main slot
  - TaskSidebar conditional rail

AppOverlays (mounted-once globals):
  - ToastViewport
  - FocusTimer
  - MorningTriageModal
  - ResizeHandles (OS-gated)

src/lib/utils/customChrome.svelte.ts holds the single source of truth
for useCustomChrome, a module-level $state both AppChrome and
AppOverlays subscribe to. Each only ever sees one loadOsInfo() call
between them.

Secondary windows still escape via their own +layout@.svelte; the
defensive isSecondaryWindow check in +layout.svelte stays so a
direct /float, /viewer, /preview navigation through the root layout
also drops the chrome.

Phase 6 per-page gate green: npm run check (0/0/5704 files),
npm test, npm run test:browser (3/3), npm run test:e2e (16/16).
No regressions in the Phase 1 smoke baseline.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 08:51:55 +01:00
c60f0aa5a5 v0.2 Phase 5: 11 primitives + gated design-system-v2 preview
Custom-styled primitives (no headless dep):
  LumotiaButton       — primary/secondary/tertiary/destructive × sm/md/lg
  LumotiaIconButton   — square icon-only; ghost/filled/destructive
  LumotiaNotice       — info/caution/danger/success inline notice
  LumotiaProgress     — native <progress> + token theming
  LumotiaField        — plain + Formsnap modes share the same markup

Bits UI 2.18.1 wrappers (warm-brutalist styling):
  LumotiaSelect       — single-select, options=[]
  LumotiaCombobox     — searchable; one-way inputValue + oninput
  LumotiaDialog       — controlled open; closable + footer snippet
  LumotiaTabs         — orchestrates List/Trigger/Content from a tabs array
  LumotiaTooltip      — wraps Provider + Root + Trigger + Content
  LumotiaMenu         — DropdownMenu items=[] with destructive variant

design-system-v2 preview route:
  src/routes/design-system-v2/+page.ts gates with VITE_LUMOTIA_DESIGN_SYSTEM_V2=1.
  Without the flag the load() throws 404 — route-level gate, not nav-
  hidden. Run via VITE_LUMOTIA_DESIGN_SYSTEM_V2=1 npm run dev:frontend
  to see the showcase.

Browser-mode component test:
  src/lib/ui/LumotiaButton.browser.test.ts. Covers render, click, and
  disabled-blocks-click. Validates that vitest-browser-svelte + the
  @vitest/browser-playwright provider land Phase 1's tooling
  contract end-to-end. 3/3 passing in Chromium.

Type fix: LumotiaIconButton and LumotiaMenu accept icon: any so
lucide-svelte's legacy SvelteComponentTyped shape composes with our
Svelte 5 wrappers without forcing a // @ts-nocheck escape hatch on
every call site. Tightens to Component<…> once lucide-svelte ships
a Svelte 5 build.

Type fix: LumotiaCombobox honours Bits UI 2.x Combobox.Root's
one-way inputValue contract. The wrapper drops bind:inputValue
and exposes an oninput callback so caller-owned filter pipelines
(HistoryPage FTS5, ModelDownloader) can drive options upstream.

Phase 5 per-page gate green: npm run check (0/0/5700 files),
npm test, npm run test:browser (3/3 in Chromium),
npm run test:e2e (16/16), guard-no-skeleton clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 08:47:53 +01:00
8c9708a508 v0.2 Phase 4: wrapper alias layer (src/lib/ui/)
Six thin alias wrappers, same prop APIs as the underlying components.
Lets pages migrate imports from $lib/components/* to $lib/ui/* one
file at a time without touching markup, and gives Phase 5+ a place
to tighten grammar without churning every call site.

  LumotiaCard           → Card.svelte
  LumotiaStatusPill     → StatusPill.svelte
  LumotiaToggle         → Toggle.svelte (forwards bind:checked, bind:loading)
  LumotiaSettingsGroup  → SettingsGroup.svelte (typed Props for svelte-check)
  LumotiaEmptyState     → EmptyState.svelte
  LumotiaPostCaptureCard → PostCaptureCard.svelte

Per the plan, the underlying components in src/lib/components/ are
untouched. They get retired during the per-page migrations in Phase 7
once no consumer remains.

LumotiaSettingsGroup mirrors the underlying Props interface explicitly
because Svelte 5's spread-into-typed-component caught a real missing-
`title` error during svelte-check. The mirrored interface keeps call
sites type-safe when importing via $lib/ui/.

Phase 4 per-phase gate green: npm run check (0/0/4135 files),
npm test (all green), npm run test:e2e (16/16), npm run
guard:no-skeleton (clean).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 08:38:23 +01:00
66e25aa778 v0.2 Phase 3: additive semantic tokens + KI-05 resolution
Additive token grammar (no renames, no replacements):

- --color-caution (dark #e8be4a, light #a08a1f) becomes the canonical
  name for tuned-amber notice surfaces in the new wrapper grammar
- --color-warning is kept as a CSS var() alias of --color-caution so
  every existing text-warning / bg-warning call site stays valid
- --color-info (dark #7a9ec0, light #3d6a8a) is the soft blue-grey
  signal for the new LumotiaNotice info variant
- --color-accent-environment (dark #8fae9a, light #4a7058) is an
  optional sage/moss support token for empty-state illustrations
  and environment-neutral status dots. NOT a brand swap — amber/
  copper --color-accent stays primary

Mirrored in src/design-system/colors_and_type.css (the buildless
preview pages bypass Tailwind so the duplication is intentional).

KI-05 resolved in the same commit, per the plan:

- src/lib/types/app.ts: drop `theme` from SettingsState
- src/lib/stores/page.svelte.ts: drop `theme: "Dark"` from defaults
- src/routes/+layout.svelte: drop the migration $effect, add a
  one-shot migrateLegacyTheme() on mount that copies any historical
  lumotia_settings.theme into preferences.theme and strips the
  legacy field. Idempotent — subsequent loads short-circuit
- src/routes/{float,viewer,preview}/+layout@.svelte: drop the same
  $effect; secondary windows inherit theme via PREFERENCES_CHANGED_EVENT
- src/lib/pages/SettingsPage.svelte: both SegmentedButton bindings
  (quick-settings row at :1272, Appearance group at :2606) now use
  Svelte 5 function bindings ({ get, set }) backed by prefs.theme
  and updatePreferences. No SegmentedButton API change

Phase 3 per-page gate green: npm run check (0/0/4129 files),
npm test (13/13), npm run test:e2e (16/16). No regressions in
the Phase 1 smoke baseline.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 08:35:54 +01:00
100e04fa70 v0.2 Phase 0+1: planning doc + tooling baseline
Phase 0 — docs/release/v0.2-frontend-overhaul.md as single source of
truth for the v0.2 frontend coherence pass. Records hard rules,
tooling pins, sacred-behaviour contract list, wrapper catalogue,
per-page migration order, verification matrix, KI-05 plan, and the
explicit "DO NOT add Skeleton" line.

Phase 1 — tooling baseline. All exact-pinned per the plan:

- @playwright/test@1.60.0 + playwright@1.60.0 + @axe-core/playwright@4.11.3
- rollup-plugin-visualizer@7.0.1 (wired behind ANALYZE=1)
- @vitest/browser@4.1.6 + @vitest/browser-playwright@4.1.6 (provider)
- vitest-browser-svelte@2.1.1 (runes-aware Svelte 5 bridge)
- cargo-nextest installed globally

New configs: playwright.config.ts (frontend-only, dev:frontend webServer,
900x700 + 1440x900 projects, visual baselines deferred), vitest.browser.config.js
(separate from jsdom suite). New scripts: test:e2e, test:e2e:ui,
test:browser, analyze, test:rust:fast, guard:no-skeleton.

guard-no-skeleton.mjs walks package.json + package-lock + src/ for any
@skeletonlabs reference and exits 1 if found — locks in the no-Skeleton
hard rule for any future agent.

Smoke baseline (tests/e2e/smoke.spec.ts): 16 tests passing across two
viewports — app loads without Tauri runtime, keyboard nav, axe scan
(color-contrast deferred to Phase 7 per docs/release/v0.1-contrast-audit.md),
light/dark theme cycle, all three sensory zones (cave/energy/reset).
10 screenshots emitted to test-results/ as non-failing artefacts.

Surfaced + fixed two browser-preview bugs while landing the baseline:

- src/lib/utils/osInfo.ts: FALLBACK_BROWSER_INFO was evaluated at SSR
  module-load (navigator undefined → os: 'unknown'), and the UA check
  ran before navigator.platform — so Playwright's Windows-UA Chromium
  on a Linux runner detected as Windows, useCustomChrome went true,
  Titlebar mounted and tripped Tauri-only APIs. Now lazy-built per
  call; platform is the primary signal, UA only a fallback.

- src/lib/components/Titlebar.svelte: defensive hasTauriRuntime() guard
  on every handler and the $effect. Titlebar should not crash if any
  future code path mounts it without Tauri.

.gitignore: reports/, .playwright/, test-results/, playwright-report/.

Per-phase gate green: npm run check (0/0), npm test (0/0), npm run
test:e2e (16/16), npm run guard:no-skeleton (clean).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 08:28:51 +01:00
3770815fbf agent: lumotia — v0.1 release-completion run
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
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.
2026-05-15 06:59:08 +01:00
bf1b68275a agent: lumotia — Pass 1 v0.1 checklist refinements + Pass 2 v0.1 UI hardening boundary doc
Operationalises the ChatGPT review of the v0.1 release-doc set into two
related landings. Both bounded; no Garden Inbox work, no architecture
refactor, no full redesign.

PASS 1 — v0.1-checklist.md refinements
=======================================

Seven targeted edits to the existing checklist:

1. Cold setup vs warm activation split. Tester acceptance test was
   conflating model-download time (variable, network-dependent) with
   UX-controlled flow time. Two-phase pass:
     - Cold setup: install → onboarding → ready-to-record (no time bound)
     - Warm activation: model-ready → first recording within 3 minutes
   Steps 1-4 are cold; 5-10 are warm.

2. Migration-aware onboarding wording. "Skip-onboarding path for users
   who already have transcripts on disk" → "Migration-aware onboarding:
   existing users with valid data are not forced through first-run, but
   can launch the tutorial manually from Settings → Help."

3. UI acceptance section. New testable items between Documentation
   surface and Quality gates — turns "redo the UI" into measurable
   requirements:
     - Main capture action visible <1s on Home
     - Recording state not communicated by colour alone
     - 10-step flow completable at 900×700 + keyboard only
     - Destructive actions reversible or confirmed
     - Every async state has sidebar status chip feedback
     - Error states preserve raw transcript + plain-words next step
     - Settings Start Here / Privacy / Accessibility findable
     - Focus ring visible everywhere
     - prefers-reduced-motion respected
     - WCAG AA contrast spot-check both modes
     - Post-capture card surfaces (display-only; NOT Garden Inbox)

4. Supported platforms scope. New subsection before smoke-test matrix
   explicitly naming:
     - Primary (must work end-to-end): Linux Fedora + Ubuntu LTS
     - Best-effort (announced if smoke-tested): macOS Apple Silicon,
       Windows 11
     - Not announced unless smoke-tested: macOS Intel

5. P0/P1/P2 smoke-test severity replacing "any  blocks tag":
     - P0 — blocks tag (tester spine on a primary platform)
     - P1 — ships only with explicit known-limitation entry
     - P2 — does not block private beta (not-announced platform / v0.2
       feature)
   Pre-tag verification confirms no unresolved P0 or undocumented P1.

6. "Telemetry" → "local activation log". Re-worded the activation
   metrics capture mechanism. Word choice deliberate — privacy-conscious
   audience reacts to "telemetry" itself. Surface: Settings →
   Diagnostics → Activation log. Nothing sent automatically.

7. Support burden signal. New activation-metric subsection covering
   the AI-assisted-indie risk that every issue becomes a support call:
     - Self-service rate ≥ 70% (issues filed to bug tracker, not inbox)
     - Diagnostic bundle (logs + system info + crash dumps; skips
       transcript content + audio by default)
     - Top-3 setup failures documented after first 5 testers

PASS 2 — v0.1-ui-hardening.md
==============================

New strict-boundary doc at docs/release/v0.1-ui-hardening.md (262
lines). Anchored on the line:

  The v0.1 UI pass is not there to make Lumotia beautiful. It is there
  to make the first successful capture inevitable.

Step 0 (before any code change): walk the 20 existing
src/design-system/preview/ files and classify each item as
already-good / needs-v0.1-hardening / v0.2-polish. Don't rebuild what
works. Inventory table inline in the doc cross-references each preview
file to the in-scope items below.

IN SCOPE (10 items, each testable):
  1. Home capture clarity — big record button, status pill, last-capture
     preview, capped Now/Tasks at 1-3 visible
  2. Recording as sacred UI state — hide settings/history/advanced
     during capture; show only timer/pause/stop/cancel + live transcript
     + level meter
  3. Post-capture card — the v0.1 headline UI artefact. Display-only
     surface of raw + cleaned + tasks + microsteps + 4 actions
     (Save/Export/StartFirstMicroStep/OpenInHistory). Explicitly NOT
     Garden Inbox: no routing, no accept/edit/park/archive, no
     backlinks, no confidence scores
  4. First-run onboarding polish — single clear next action per step,
     pre-supplied prompt for test recording, graceful failure recovery,
     skip-to-main escape hatch (tracked as known-limitations follow-up)
  5. Settings sanity pass — 6 sections in order: Start Here /
     Transcription / Models / Tasks / Accessibility / Privacy / Advanced.
     Full 7-group progressive-disclosure regroup deferred to v0.2
  6. Error-state copy sweep — every error preserves raw transcript,
     explains in plain words, says next user action, no stack traces
     user-facing
  7. Keyboard flow — entire 10-step tester acceptance completable by
     keyboard only, focus ring visible, no hover-only controls
  8. Responsive at 900×700 + 1440×900 ONLY — ultrawide / mobile / split-
     screen deferred to v0.2 unless a tester reports them
  9. Accessibility practical checks (WCAG-style, not certification) —
     keyboard, focus, not-colour-alone, reduced motion, contrast spot-
     check, literal-words status labels, form-label association
  10. Status labels everywhere — new StatusPill component (no existing
     class found in survey); add to design-system/preview/components-
     status-pills.html. Pill states: Ready / Recording / Paused /
     Transcribing / Cleaning / Extracting tasks / Saved / Exported /
     Needs review / Failed safely

OUT OF SCOPE (the traps to refuse — each ships in v0.2 or later):
  - New visual identity (brand book v3 PDF is locked)
  - New navigation model
  - Garden Inbox (review cards, routing, accept/edit/park/archive,
    related notes, backlinks, P-P-T detection)
  - Suggested routing
  - Backlinks
  - Graph view
  - Canvas view
  - New animation system
  - Full SettingsPage 7-group redesign
  - Obsidian plugin
  - Cloud / provider UI

Plus a "Definition of done" with 8 specific completion criteria, and
cross-references to checklist + Garden roadmap + how-built + design-
system preview + locked brand book.

VERIFICATION
============
- cargo fmt --check: clean (no Rust touched)
- All four release docs cross-reference cleanly
- No new tests required (boundary docs, not code)
- v0.1 ship gate unchanged in shape, sharpened in detail
2026-05-14 22:12:21 +01:00
c5460a169c agent: lumotia — release-doc set + two pre-release audits (MCP + LLM failure)
Operationalises the ChatGPT/Jake roadmap-synthesis pass into four
release-boundary documents at docs/release/. Synthesis call:

  v0.1 = stable local capture product
  v0.2 = Garden Inbox / review cards
  v1.0 = PKM-complete + commercial track

Two factual audits ran first per Jake's explicit instruction — release
hardening only, no architecture refactors, no Garden Inbox work:

AUDIT 1 — MCP surface
=====================
Verdict: PASSES the v0.1 trust posture.
- Read-only by design (`//! No writes — Lumotia's Tauri app remains the only writer`)
- Stdio-only transport (newline-delimited JSON-RPC 2.0); no TCP/Unix
  listener, no bind, no network exposure
- Database opened via `lumotia_storage::init_readonly` — structurally
  enforced, not just convention
- 4 tools, all SELECT-only: list_transcripts, get_transcript,
  search_transcripts, list_tasks
- Zero matches for INSERT/UPDATE/DELETE/fs::write/fs::remove/
  create_dir/spawn_blocking in the crate
- Separate binary (`crates/mcp/src/main.rs`) — not part of the running
  Tauri app; user must explicitly launch and wire into client config
- Honest nuance flagged in known-limitations: a wired client gets read
  access to the entire transcript history + task list — no per-row
  permission boundary in v0.1

AUDIT 2 — LLM failure surface
=============================
Verdict: data-loss path PASSES; UX-wedge path PARTIAL (documented).
- post_process_segments (file + live pipeline): tracing::warn! on Err,
  segments stay at rule-based output. Raw transcript preserved.
- cleanup_transcript_text_cmd (DictationPage): frontend try/catch
  returns raw text unchanged on Err. Raw transcript preserved.
- extract_tasks_from_transcript_cmd (DictationPage): frontend falls
  back to rule-based extractTasks (regex + verb list) on Err.
- extract_content_tags_cmd (HistoryPage): per-row try/catch; toast on
  failure; transcript untouched.
- Hung llama.cpp: no tokio::time::timeout on the spawn_blocking call.
  Raw transcript preserved; rest of app functional; LLM status chip
  stays on "Cleaning up" until restart. Soft edge — documented in
  known-limitations as v0.2 hygiene candidate. Not implemented per
  "release hardening only" instruction.

THE FOUR DOCS
=============

docs/release/v0.1-checklist.md
  - 10-step tester acceptance test (install → capture → cleanup →
    task → MicroSteps → timer → history search)
  - Must-ship list per surface (product, onboarding, artefacts, docs,
    quality gates, trust+security, release-blockers, smoke-test
    matrix)
  - Activation metrics for private beta (3 min to first capture, 3
    captures in 24h, 7-day return, etc.) + v0.1 public launch
    (20 install, 15 first-capture, 10 return, 5 pay-£39)
  - Pre-tag verification sequence
  - Explicit out-of-scope list (Garden Inbox, Phases B-E/G/I/J, etc.)

docs/release/v0.1-known-limitations.md
  - User-facing rewrite, not engineer-speak
  - Power assertions per platform (Linux idle / macOS App Nap / Windows
    sleep) with practical workarounds
  - MCP read-only/local-only posture with the
    "all transcripts visible to your wired client" honest nuance
  - AI cleanup/extraction failure table — what fails, what you see,
    what's preserved
  - Settings page progressive-disclosure status
  - Internal engine refactor (orchestrator dormant) framed for users
  - Explicit "what's NOT in v0.1" call-outs
  - Reporting issues + crash-dump location

docs/release/v0.2-garden-roadmap.md
  - Headline: "review cards for turning messy dictations into notes,
    tasks, topics and links" — tangible, not PKM-overloaded
  - Garden Inbox scope (raw / cleaned / suggested title-type-folder-
    project / extracted tasks / suggested tags / possible links /
    confidence / Accept-Edit-Park-Archive)
  - Engine architecture Phases B-E pairing
  - Explicit "NOT in v0.2" list (no graph, no canvas, no PKM marketing,
    no cloud provider, no premium voices)
  - Open decisions for v0.2 scope freeze deferred until v0.1 ships +
    20 testers run

docs/release/how-lumotia-is-built.md
  - Public-facing trust page; honest disclosure that AI-assisted
    human-directed, then evidence
  - The real silent-data-loss bug the drill caught (Phase A.7 fix
    ff8dda0) framed as proof the process works
  - Phase B atomiser audit: 9 surgical fixes including the FIFO hang,
    LlmEngine unload race, purge-vs-restore SELECT-then-DELETE race
  - Supply-chain pre-flight (npm audit signatures + --ignore-scripts +
    pinned dev deps + pinned rust toolchain)
  - MCP read-only audit + LLM failure audit cross-referenced
  - Anti-patterns explicitly avoided (no telemetry exfiltration, no
    silent AI dependency, no "audit log later", etc.)
  - Calibrated to "AI use is survivable; sloppy undisclosed untested
    AI use is not" — RPCS3 framing cited

Verification:
- cargo fmt --check: clean (no Rust changed)
- All four docs are user-readable, not commit-log-derivative
- Cross-references resolve (every internal path quoted exists)
2026-05-14 21:49:54 +01:00