Product and Scope
Product statement
Build a private, reliable note-taking app in which people write and retain notes as Markdown, group them into notebooks, and can recover or inspect every saved version. The initial release provides native experiences on Android and iOS, while sharing business logic through Kotlin Multiplatform (KMP).
The app must work without a network connection. The initial release is fully local: it does not connect to a sync destination. Its data model and module boundaries will nevertheless leave a deliberate path for a future sync system, while the application remains the authoritative owner of local notes and revision history.
Product principles
- Local first. Creating, editing, searching, and viewing notes must not depend on an account, connection, or remote service.
- Markdown is the document format. A current note is represented as portable UTF-8 Markdown, with app-specific metadata kept separate where possible.
- History is never silently lost. Every durable content change creates a locally retained revision. Pruning, if introduced later, is explicit and recoverable where possible.
- Native feel, shared rules. Android and iOS use platform-native UI and input behavior; domain rules, persistence contracts, future-sync boundaries, and test cases live in KMP.
- Sync is designed, not shipped. Future destinations will declare their capabilities; a file-copy destination must not be represented as offering remote history or conflict-free collaboration.
- Extensions are constrained integrations. A future plugin system will extend defined capabilities without gaining unrestricted access to notes or app internals.
Primary users and jobs
| User need | First-release capability |
|---|---|
| Capture and revise a thought quickly | Create/edit Markdown note with autosave and offline persistence |
| Keep related material together | Create, rename, archive, and browse notebooks; notes created outside a notebook live at the top level; pin important notes |
| Clean up or reorganize many notes at once | Press-and-hold multi-select with select all, then move or delete together |
| Capture a thought instantly | Quick capture from the app icon’s long-press menu: blank note, keyboard up, no title or notebook to choose |
| Never name notes by hand | Automatic titles from an on-device model when available, otherwise the first line |
| Fix a mistake without being interrupted | Undo bar after delete or move instead of confirmation dialogs |
| Connect related notes | Type [[ to link a note; tap a link to open it, back returns |
| Jump to another note while reading one | Fuzzy note lookup from inside a note; back/forward move between the notes visited |
| Recover an earlier draft | Browse a note’s revision timeline and restore or copy a prior revision |
| Write formatted notes without leaving the keyboard | Keyboard accessory formatting toolbar |
| Track a small set of actions inside a note | Create Markdown checklists and check/uncheck items directly in the rendered/editor experience |
| Keep notes available elsewhere | Future: connect a supported sync destination and see its state |
| Maintain a folder of Markdown files on Android | Future: install/use a local-folder sync extension |
Release 1 scope
In scope
- Android and iOS apps with native UI.
- Notebook list, note list, note editor, note detail/history view, and settings.
- A live-preview, rich editing experience on Android and iOS. Markdown is the canonical stored format, but its syntax is not exposed in the normal editing or reading UI.
- Keyboard accessory toolbar for common Markdown actions: heading, bold, italic, strikethrough, checklist, bullet list, numbered list, quote, code, link, undo, and redo.
- Interactive task lists: users can add checklist items and check or uncheck them in a note. Toggling updates the underlying Markdown representation and is saved as a normal note revision.
- Local encrypted-at-rest storage when platform support is selected; at minimum, secure platform storage for secrets and a documented local-data protection posture.
- Immutable local revisions for note content and important note metadata changes.
- Search across local current notes.
- A documented future-sync placeholder: stable IDs, local revision parentage, portable Markdown metadata boundaries, and adapter/capability contracts. It has no configured destinations, transfers, permissions, status UI, or background work in Release 1.
- Export/import of current Markdown notes and notebooks, with documented behavior for history.
Explicitly out of scope for Release 1
- Real-time collaborative editing and shared notebooks.
- Any operational sync destination, cloud account, remote transfer, sync status UI, or background sync.
- Android local-folder sync and installation/distribution of sync plugins.
- A proprietary hosted cloud service or user accounts.
- Desktop or web clients.
- Arbitrary third-party executable plugins on iOS.
- End-to-end encrypted multi-device cloud sync unless a specific cloud destination is selected and designed.
- Rich-text document storage as the source of truth; Markdown remains canonical.
- Attachments beyond references/links. Attachment storage can be designed later without blocking Markdown notes.
Experience requirements
Core navigation
The user can move from the top-level list to a note editor in one or two actions. A note may be moved between notebooks.
Organization layout
The hierarchy has exactly two levels:
- Top level holds notebooks and the notes that are not in any user-created notebook.
- Notebooks hold only notes. A notebook cannot contain another notebook, so notebooks never nest.
Every note belongs to exactly one notebook. A note created outside any notebook goes into a built-in default notebook. The default notebook is never displayed as a notebook: its notes appear at the top level as if they were unfiled. The user cannot rename, delete or archive it (see D-15).
Pinned notes. The user can pin and unpin notes.
- Pinned notes in the default notebook are shown at the very top of the top-level list, above notebooks and unpinned notes.
- Pinned notes in a user-created notebook are shown at the top of that notebook’s note list only, not on the top-level list.
- Among pinned notes in the same list, the one most recently edited is first.
- Pinning or unpinning is not an edit: it creates no revision and does not change the note’s last-edited time or its position among other pinned notes.
Deleting a notebook. Deleting a notebook never deletes its notes. They move to the default notebook and appear at the top level. A user who wants the notes gone too deletes them first (see multi-select below) and then deletes the notebook.
Multi-select. In any note list (top level or inside a notebook), pressing and holding a note enters selection mode with that note selected. In selection mode the user can select or deselect further notes by tapping, choose Select all, and then Move the selected notes to another notebook (including the default notebook) or Delete them together. Delete follows the normal trash and restore rules. Leaving selection mode (back or a cancel control) changes nothing.
Quick note lookup and note-to-note navigation
While viewing or editing a note, the user can open a lookup that fuzzy-searches notes and jump directly to a result, without first leaving to the notebook or note list. Results are matched against note titles first and then note bodies: title matches rank above body-only matches, and within each group better matches rank higher.
Navigation after a lookup behaves like a browser history:
- Jumping from note A to note B via lookup opens B.
- Back returns to note A, not to the notebook list or out of the note.
- Forward, after going back, returns to B.
- Repeated lookups extend the history in the same way (A → B → C; back goes to B, then A).
The history has no fixed length limit within a session. It is not persisted: when the app is closed and reopened, it opens on the note that was open last, with an empty history. When the history has no earlier note, back leaves the note as it does today. Opening a lookup result while there is unsaved text in the current note saves that note first (D-14).
Quick capture
Getting a thought down must take no decisions. Quick capture opens a blank new note with the keyboard already up and nothing else to fill in: no title, no notebook choice. The note goes into the default notebook, and the user can move it later.
- App-icon quick action. Long-pressing the app icon (Android app shortcut, iOS Home Screen quick action) shows a Quick capture action. Choosing it launches the app straight into a blank note as above.
- An empty note is never kept: leaving a quick-capture note without typing anything discards it and creates no revision.
- Quick capture follows the normal autosave rules (D-14).
Widgets, share-sheet capture and other entry points are future options, not Release 1.
Automatic titles
The user never has to type a title. The app creates one from the note’s content:
- If the device offers a local, offline language model, the app asks it for a short title for the note. Nothing is sent off the device. The target models are Apple’s on-device Foundation Models (iOS 26+ on Apple Intelligence-capable devices) and Android’s Gemini Nano through ML Kit GenAI / AICore on supported devices. Availability varies by device, OS version and settings, so the app checks it at runtime.
- If no such model is available, or it is not ready, fails or returns nothing usable, the app uses the first line of the note as the title. This is also the immediate title shown before a generated one arrives.
Generating a title never blocks typing or saving, and the first-line fallback is always available. While the title is automatic, a generated title replaces the first line a few seconds after the note is opened, saved or has its title cleared. A title the user typed is never replaced automatically. The user can ask for a new one at any time with Generate title in the title dialog; it is shown only when the model is ready. Titles are written in the note’s language when it can be detected, otherwise in the device’s language. See D-23, D-28 and D-30.
Undo instead of confirmation
Destructive actions do not ask “Are you sure?”. They happen immediately and show a brief Undo bar at the bottom of the screen. This applies to deleting a note, deleting several selected notes, and deleting a notebook. Tapping Undo puts everything back exactly as it was: deleted notes return to where they were, and a deleted notebook returns with its notes in it. If the bar times out or is dismissed, the action stands under the normal trash rules (notes can still be restored from Trash; see D-21 for notebooks). Moving notes shows the same bar so a wrong move is one tap to reverse.
Trash. The Trash screen’s More (three dots) menu offers Select and Empty trash. Notes can be selected there (press and hold, or Select) and restored together with Restore selected. Empty trash works like the other destructive actions: the notes disappear at once and an Undo bar appears. They are deleted forever, with their history, only once the bar has gone; if the app closes first, they stay in the trash (D-40).
Links between notes
Users can link one note to another while writing, and tap a link to go there.
-
Creating a link. Typing
[[in the editor opens the same fuzzy note lookup used elsewhere (D-17). The link toolbar button opens one text field, with no choice to make first. The user types, and the app decides what kind of link it is:- If the text looks like a web address (it starts with a scheme such as
http://,https://ormailto:, starts withwww., or looks like a domain such asexample.com/page, with no spaces), it becomes a web link. The field shows the address as the top suggestion, and confirming inserts it. - Otherwise it is treated as a note link: the field shows matching notes from the fuzzy lookup, and choosing one inserts a link to that note at the cursor. When nothing matches, the field offers to create a new note with the typed text as its title and link to it.
- If the text is selected in the note when the button is pressed, it becomes the link’s label and the field starts with that text.
- If the text looks like a web address (it starts with a scheme such as
-
Addresses typed as text. In the read view, a web address written as plain text (starting with
https://,mailto:… orwww.) is shown as a link and opens when tapped. The note’s text is not changed (D-29).Typing
[[always means a note link and skips the web-address check. -
Appearance. A note link looks like a link in the live preview; the user never sees link syntax.
-
Following a link. Tapping a note link opens the target note. It counts as a jump in the note history (D-17): back returns to the note the user came from, and forward returns to the link’s target.
-
Stable. A link points to the target note by its ID, so renaming or moving the target does not break it.
-
Label. A link shows the target’s current title, so it changes when the target is renamed. If the user linked selected text or typed inside the link’s label, the link keeps those words (D-39).
-
Missing targets. If the target note is in Trash or deleted, the link is shown as unavailable and tapping it says why, with a one-tap Restore when the note is in Trash.
See D-25 and the data-model section on note links for storage.
Editing and formatting
The editor is always a live preview: headings, emphasis, lists, links, quotes, code, and task checkboxes are displayed as their formatted forms while the user edits. Markdown remains an implementation detail used for storage, export, import, and future sync; there is no source-editing mode or Markdown-syntax toggle in the product UI.
Formatting commands apply a semantic operation to the current selection, block, or cursor position, with predictable cursor placement and behavior on an external keyboard. The editor serializes the resulting document back to canonical Markdown without exposing that serialization. Native text editing behavior, accessibility, spell-check, selection handles, and input-method integration stay in each platform UI.
Task-list items appear as accessible checkbox controls, not Markdown markers. Toggling preserves surrounding formatted content, works offline, and creates a revision only when the checked state actually changes. Nested task items are supported as nested visual lists; task scheduling, reminders, recurrence, and cross-note task views are future extensions, not Release 1 requirements.
Revision history
The history screen shows timestamp of the change in HH:MM format in local timezone. There is no second level history. The user can preview a revision, copy it into a new note, or restore it as a new current revision. Restoring never overwrites the old current revision. The preview shows what that version changed compared with the version before it, each change with the rest of its line (D-37, D-38), above the version’s full text.
History lists only versions that came from writing, restoring, importing or copying. Moving a note to another notebook, to the trash or back from the trash is not shown, and restoring a version never moves the note (D-43).
Each version shows what changed compared with the version before it (D-37). Each change appears with the unchanged rest of its line before and after it, at most about 100 characters on either side (D-38). Deleted text has a mild red background and added text a mild green background. Formatting changes are not shown as changes. A version whose only changes are formatting says so. The first version shows its whole text as added.
Future-sync design boundary
Release 1 exposes only local-save state. During design, preserve stable note and revision identities, current-revision parentage, and a portable Markdown/export representation so a future destination can be introduced without rewriting user data. Sync settings, connection flows, destination status, retries, and permission errors are deferred until an actual destination is built.
Success criteria
Release 1 is ready for a limited beta when:
- Notes can be created, edited, moved, searched, and deleted/restored locally without data loss across app restarts.
- Each saved edit produces an inspectable local revision, and restoring a revision results in a new revision.
- The editor toolbar produces predictable formatted results for selected text and empty selections, including task-list insertion; the saved Markdown remains valid without being shown to the user.
- Users can check and uncheck task items on Android and iOS; the persisted Markdown, revision history, and search index reflect the resulting state.
- The documented placeholder captures the future sync capability model without shipping any destination implementation or network behavior.
- Core rules have automated KMP tests; Android and iOS have targeted UI/integration coverage.