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.
This commit is contained in:
2026-05-15 06:59:08 +01:00
parent bf1b68275a
commit 3770815fbf
77 changed files with 8697 additions and 1017 deletions

View File

@@ -2,7 +2,7 @@
name: v0.1-ui-hardening
type: release
tags: [release, v0.1, ui, hardening, boundary, no-redesign]
description: "Strict scope boundary for the v0.1 UI hardening pass. Goal: make the first capture flow obvious, calm, responsive and hard to break. NOT a redesign. Lists in-scope items (home clarity, recording-as-sacred-state, post-capture card, settings sanity, error copy, keyboard flow, two-size responsive check, accessibility practical checks) and out-of-scope traps (full redesign, new identity, Garden Inbox, suggested routing, graph view, animation system, Obsidian plugin, cloud UI). Pairs with docs/release/v0.1-checklist.md UI acceptance section."
description: "Strict scope boundary for the v0.1 UI hardening pass. Goal: make the first capture flow obvious, calm, responsive and hard to break. NOT a redesign. Lists in-scope items (home clarity, recording-as-sacred-state, post-capture card, settings sanity, error copy, keyboard flow, two-size responsive check, accessibility practical checks) and out-of-scope traps (full redesign, new identity, Garden Inbox, suggested routing, graph view, animation system, Obsidian plugin, cloud UI). Pairs with docs/release/v0.1-checklist.md UI acceptance section. Annotated 2026-05-14 with completion-status — see docs/release/v0.1-completion-status.md for the full audit trail."
---
# Lumotia v0.1 UI hardening — scope boundary
@@ -15,6 +15,8 @@ The v0.1 UI pass is not there to make Lumotia beautiful. It is there to make the
The product is already feature-rich. The UI's job in this pass is to **hide that richness until needed** so the tester acceptance flow (`docs/release/v0.1-checklist.md`) is unmistakable.
> **Status (2026-05-14):** All in-scope code items completed. The 10-step keyboard-only walk + 900×700 visual verification + WCAG-AA spot-check are 👤 human-required gates. See `docs/release/v0.1-completion-status.md` for per-item state.
## Mantra for every UI decision in this pass
Every screen should answer in under 1 second:
@@ -36,6 +38,8 @@ Before any UI change, walk through the existing 20-file preview at `src/design-s
The classification itself is the first deliverable of this pass. Do not rebuild what is already working.
> 🔶 Status: the 20-file inventory was catalogued in recon. `components-status-pills.html` was added as the 21st preview file. A formal "good / minor-hardening / v0.2-polish" classification document was NOT filed in this pass — recommend walking the preview shell next time you're in design-system view.
Existing preview files (auditable surface):
| File | Surface | Reuse for |
@@ -46,6 +50,7 @@ Existing preview files (auditable surface):
| `components-empty-states.html` | Empty state | Pre-first-recording Home, empty History, empty Tasks |
| `components-inputs.html` | Form controls | Settings + onboarding inputs |
| `components-nav.html` | Navigation | Sidebar / tab patterns; recording-state simplification |
| `components-status-pills.html` | Status pill vocabulary | **NEW in v0.1** — 10-state pill catalogued |
| `components-toasts.html` | Toast vocabulary | Error-state surfacing, save confirmations |
| `spacing-motion.html`, `spacing-radii.html`, `spacing-scale.html`, `spacing-shadows.html` | Spacing tokens | Layout density at 900×700 |
| `type-body.html`, `type-headings.html`, `type-transcript-mono.html` | Typography | Status pill labels, post-capture card content |
@@ -64,6 +69,8 @@ The Home / capture screen must answer the four questions a first-time user has o
- What happens next? → Visible affordance to where the recording will go
- Where did my last capture go? → Last-capture preview surfaced on Home
> Status: ✅ — DictationPage record button enlarged to 80×80px; profile + model summary line added; `<StatusPill>` swap completed; last-capture preview added (collapsed `<details>`); secondary CTA count audited (≤ 3 unconditional).
Structure target:
```
@@ -91,6 +98,8 @@ Secondary nav
While recording is active, the app simplifies itself. The user has one job — capture their thought — and the UI must not present competing choices.
> Status: ✅ — `src/lib/Sidebar.svelte` greys + sets `aria-disabled="true"` + `tabindex={-1}` on nav buttons during `page.recording`. 200ms fade transition wrapped in `prefers-reduced-motion`. DOM is preserved (not removed) so screen-reader users can still navigate.
Hidden or de-emphasised during recording:
- Settings, History, Tasks navigation (secondary nav greys / collapses)
@@ -113,6 +122,8 @@ Recording is not the moment to present choices.
After the user stops dictation, surface one clear card as the landing moment. The card is the visual model future Garden Inbox cards extend, but it ships in v0.1 with display-only behaviour.
> Status: ✅ — `src/lib/components/PostCaptureCard.svelte` built + integrated into `src/lib/pages/DictationPage.svelte`. Card surfaces after every recording when cleanup completes; hidden the moment a new recording starts.
**v0.1 post-capture card (display-only):**
- Raw transcript (collapsible, always preserved)
@@ -144,6 +155,8 @@ Scope already locked in `v0.1-checklist.md` under "First-run onboarding". This p
- Failure at any step recovers gracefully (no dead-end "something went wrong" screens)
- A skip-to-main option exists for users who fail the tutorial but want to proceed (they show up in known-limitations as the next support burden)
> Status: ✅ for the polish layer — pre-supplied prompt step added (`"Today is a good day to test my microphone..."`); failure recovery (Try again + Skip this step buttons on every error path); skip-to-main preserved. 🔶 The actual recording within the step uses the documented "open the main app and try recording there" fallback rather than inline recording — see `docs/release/v0.1-completion-status.md` for rationale.
### 5. Settings sanity pass
Group the existing settings into six sections in this order, visible without scrolling on a 900×700 window:
@@ -158,6 +171,8 @@ Group the existing settings into six sections in this order, visible without scr
The full 7-group progressive-disclosure regroup with search box is **deferred to v0.2**. The v0.1 pass is "the basics are findable", not "every setting is grouped beautifully".
> Status: ✅ — `src/lib/pages/SettingsPage.svelte` regrouped into Start Here / Transcription / Models / Tasks / Accessibility / Privacy / Advanced (collapsed by default) / Help (preserves the tutorial-replay button + support links). Activation log surface added under Privacy with opt-in toggle, event table, clear button.
### 6. Error-state copy
Every visible error message must:
@@ -169,6 +184,8 @@ Every visible error message must:
Sweep every error surface in the codebase and rewrite to match. Reuse `components-toasts.html` vocabulary for transient errors; reuse card empty-state vocabulary for sustained errors.
> Status: ✅ — DictationPage (6 sites) + SettingsPage (4 sites covering 9 catch paths) swept. `<StatusPill status="failed-safely" />` next to the explainer when data was preserved; `<StatusPill status="needs-review" />` when the user must act. Technical detail folded into `<details>` blocks. Every error surface ends with a concrete next-action button.
### 7. Keyboard flow through the tester acceptance path
The entire 10-step tester acceptance flow must be completable using keyboard only. Minimum keyboard paths:
@@ -184,6 +201,8 @@ The entire 10-step tester acceptance flow must be completable using keyboard onl
Focus ring must be visible on every interactive element at default zoom. No `:hover`-only controls — every action has a keyboard-reachable trigger.
> Status: ✅ infrastructure — Ctrl+K (or ⌘+K) opens History + focuses search; Ctrl+, (or ⌘+,) opens Settings; Esc dispatches `lumotia:escape` (modals own their close logic); arrow keys traverse PostCaptureCard tasks + Enter starts MicroStep timer; global `:focus-visible` rule in `src/app.css` covers all interactive elements; textarea no longer uses `focus:outline-none`; no `group-hover:` patterns found app-wide. 👤 walking the entire 10-step flow personally is the verification.
### 8. Responsive test at 900 × 700 and 1440 × 900
These two sizes catch the biggest layout failures without turning this into a responsive-design project. Pass condition:
@@ -193,6 +212,8 @@ These two sizes catch the biggest layout failures without turning this into a re
Ultrawide, mobile-portrait, and split-screen edge cases are explicitly **deferred to v0.2** unless a tester actively reports them.
> 👤 HUMAN REQUIRED: visual verification at the two target viewports.
### 9. Accessibility practical checks (WCAG-style, not certification)
The pass-bar for v0.1 is "the core flow is not hostile", not "fully WCAG 2.2 AA conformant". Concrete checks against the WCAG framework's perceivable / operable / understandable / robust pillars:
@@ -207,6 +228,8 @@ The pass-bar for v0.1 is "the core flow is not hostile", not "fully WCAG 2.2 AA
The full WCAG 2.2 AA conformance audit is v0.2.
> Status: ✅ for code-side items (focus, motion, status-pill literal labels, form labels — verified by `npm run check` strictness). 👤 contrast spot-check + keyboard walk are human-required.
### 10. Status labels everywhere
Use plain status pills for every async state. Do not rely on colour, icons, or animation alone. The pill labels:
@@ -224,6 +247,8 @@ Use plain status pills for every async state. Do not rely on colour, icons, or a
The `StatusPill` component is a new build (no existing class found in survey). Add it to `src/design-system/preview/components-status-pills.html` so it joins the catalogued surface.
> Status: ✅ — `src/lib/components/StatusPill.svelte` built; `src/design-system/preview/components-status-pills.html` added; integrated into DictationPage + PostCaptureCard + SettingsPage error surfaces. Vocabulary covers all 10 required states.
## Out of scope (the traps to refuse)
Each item below is a real temptation. Each ships in v0.2 or later. Touching any of them in this pass moves the v0.1 ship date.
@@ -240,23 +265,34 @@ Each item below is a real temptation. Each ships in v0.2 or later. Touching any
- **Obsidian plugin.** Markdown export already exists. The plugin itself is a v0.2 ecosystem play.
- **Cloud / provider UI.** `lumotia-cloud-providers` stays compiled-but-dormant per the v0.1 checklist.
> Status: ✅ — none of the out-of-scope items were started in this pass.
## Definition of done for the UI hardening pass
This pass is complete when:
1. The design-system preview classification is filed (step 0)
> 🔶 Partial — 21-file inventory is current; formal classification doc not filed.
2. Every in-scope item ships a focused commit referencing this doc
> 🔶 Code landed; commits to be created when the user is ready (see `docs/release/v0.1-completion-status.md` for the file list).
3. The UI acceptance section in `v0.1-checklist.md` is fully ✅
> Partial — code-side items ✅; visual + keyboard walks remain 👤.
4. The 10-step tester acceptance flow has been walked end-to-end at 900 × 700 with keyboard only
> 👤 HUMAN REQUIRED.
5. The post-capture card is on disk, surfacing after every recording
> ✅ — `src/lib/components/PostCaptureCard.svelte` + DictationPage integration.
6. The `StatusPill` component is in `src/design-system/preview/components-status-pills.html` and used everywhere an async state appears
> ✅ — preview file added; integrated app-wide.
7. The error-state sweep has touched every visible error surface
> ✅ — DictationPage + SettingsPage swept; remaining `err.message` references are inside `<details>` blocks.
8. No item from the out-of-scope list has been started
> ✅.
## Cross-references
- `docs/release/v0.1-checklist.md` — the UI acceptance section pairs with this doc
- `docs/release/v0.1-completion-status.md` — full audit trail for the 2026-05-14 completion run
- `docs/release/v0.2-garden-roadmap.md` — Garden Inbox extends the post-capture card pattern
- `docs/release/how-lumotia-is-built.md` — references the dogfood drill + atomiser audit; UI hardening adds the user-facing trust layer
- `src/design-system/preview/` — the 20-file existing visual vocabulary to inherit from
- `src/design-system/preview/` — the 21-file existing visual vocabulary to inherit from
- `outputs/lumotia/lumotia-brand-book-v3.pdf` — locked brand identity (not opened in this pass)