Mobile Checklist Experience

Create and complete lists on iPhone  ·  plan source: .claude/plans/mobile-checklist-experience.md  ·  2026-07-21

What we're building on

Already working
  • Checked state syncs for free — content is one markdown string through SyncEnvelope, field-level LWW
  • ChecklistMarkdown in NoteSparrowCore is pure Foundation and parses both checkbox forms — the iOS renderer reuses it, no new dialect
  • Dictation's Done-moment offer already creates [ ] lists (passed round-1 step 12)
Missing or broken
  • No way to check off an item on iOS — the core unmet need
  • No add-item or convert-to-checklist affordance on mobile
  • Resumed dictation drops the second list 2 root causes found — whole-transcript averaging suppresses the offer, and sustained listening silently gives up after 5 empty windows

Interaction model — settled 2026-07-21

The target decides what a tap means, not a mode

Accepted limitation: the transition tap can't carry its location into TextEditor — entering edit lands the cursor at the end. Once inside, native tap-to-place-cursor works normally everywhere. (iOS 18 TextSelection is a future refinement, not a dependency.)

Key decisions

Read-mode-first note view — not a rich editor. Opening a note renders checklist lines as native tappable rows (checked = dimmed + strikethrough, display-only); everything else is plain text, never rewritten. Edit button / tapping plain text flips to the untouched TextEditor. Empty notes open straight to edit. This is the smallest architecture that makes checklists tappable and it honors the "Mac is the primary editor" blueprint constraint.
Toggle = marker swap + immediate persist. Tap swaps [ ][x] in the string and saves instantly (bypassing the 2s debounce, same persist-now pattern voice capture uses) — shrinking the known ~1s LWW race window. Rapid toggles coalesce in the existing 1s sync flush.
Three creation paths, smallest-first. Dictation offer (shipped) → "Add item" row at the end of each checklist block (also how you extend the list in the store) → "Convert to Checklist" menu action for plain-line notes, with a discoverable hint when a note looks list-shaped. No smart Enter-continuation inside TextEditor — SwiftUI offers no return-key interception there.
Both dictation defects get fixed here, not deferred. They gate the exact use case driving the priority shift. Detection becomes segment-aware; sustained listening must never silently drop audio — reset the give-up counter on voice activity, and if we truly stop, end the session visibly.

Phases

P1Shared Checklist Document ModelCore · no deps
P2Read-Mode Renderer with Tap-to-ToggleiOS · after P1
P3Mobile Creation AffordancesiOS · after P2
P4Dictation Reliability — the Resume Bugparallel · no deps
P5Cross-Device Verification & Docsafter P1–P4

Final review

Pros. Smallest architecture that delivers tap-to-check; reuses the shared parser; touches no edit/save/sync plumbing; every phase ships value alone; dictation fixes target root causes found by code reading.

Cons, stated plainly. (1) Read-mode-first changes tap-to-edit muscle memory for all notes — now de-risked: the interaction model was walked through the shop flow and settled; residual cost is the cursor-at-end transition tap. (2) Two toggle surfaces widen exposure to the known ~1s LWW window; simultaneous Mac+iPhone toggles resolve to one writer — documented, not fixed (per-line merge would be a sync-engine project). (3) Defect B's fix leans on the level meter distinguishing voice activity; fallback is honest-but-less-magical visible session end. (4) Segment-scoped conversion has fiddly range bookkeeping — the likeliest task to slip, and whole-transcript offers still work if it does.

Edge cases to watch. Very large notes re-parsing per keystroke in the add-item field; RTL/localized strikethrough; a Mac edit turning a checklist line into prose while the phone's read view is open mid-tap.

85
confidence this is the optimal, most elegant plan for the core request (82 → 85 after the interaction model was settled)