Architecture decision records

Every decision that shaped the app, with the reasoning kept next to it.

Each record states the situation, the decision taken, and what it costs. Superseded records stay published and point at their replacement.

01records

Newest first.

  1. ADR-0058

    A folder's board can be embedded in a note

    ADR-0057 made database views a route and rejected an embedded block, because a React grid inside ProseMirror would pull cross-note projections into the editing…

  2. ADR-0057

    Database views are a route over note properties

    Notes carry typed properties (note properties), but the only place to read or change them was one note's metadata panel.

  3. ADR-0056

    Account deletion purges cloud data before local reset

    Account & sync offers a guarded account deletion action. The authenticated Worker records a deletion tombstone before purging the account's sync Durable…

  4. ADR-0055

    Workspace module boundaries

    apps/workspace/src holds 23 feature folders next to shell, commands, store, bridge (now platform), contracts, and shared.

  5. ADR-0054

    Recurring tasks repeat in the document

    ADR-0053 put a task's due date on its checklist line so Markdown, exports and other editors keep it.

  6. ADR-0053

    Task due dates live in the checklist line

    WorkspaceTask has carried a dueDate since ADR-0031, but nothing set it. A date that only exists in SQLite would disappear from the note's Markdown, so an…

  7. ADR-0053

    Math blocks and the dollar trigger

    Notes need inline and display math. The portable Markdown spelling that Obsidian, GitHub, Pandoc, and most static site generators read is $...$ for inline math…

  8. ADR-0052

    Public note links

    Users want to send a note to someone who does not use Skriuw: a read-only page on skriuw.com behind a link.

  9. ADR-0051

    Remote images download once at import, with consent

    ADR-0023 keeps remote images in imported Markdown as blocked placeholders so that opening a note can never fetch from the network.

  10. ADR-0050

    oxfmt and oxlint gate the v2 TypeScript

    The v2 gate checked Rust with cargo fmt and cargo clippy -D warnings, but TypeScript only with tsc.

  11. ADR-0049

    Group the v2 repository by product boundary

    The v2 product had accumulated top-level application, service, and shared TypeScript directories.

  12. ADR-0049

    One shared icon system, Fluent Regular, motion as data

    Icons were drawn three different ways. The desktop hand-copied about 120 Lucide drawings into apps/workspace/src/shared/icons/static.tsx and normalised their…

  13. ADR-0048

    A native mobile shell over the shared Rust core

    Skriuw reaches phones today as the installed browser build: the compact shell (ADR-0041, ADR-0047) over worker-owned SQLite WASM and OPFS (ADR-0027).

  14. ADR-0047

    The compact shell owns the back gesture and the install offer

    ADR-0040 made the browser build installable and ADR-0041 gave it a phone layout. Installed on Android, three platform behaviours still read as a website:

  15. ADR-0046

    Per-account local workspaces

    A cloud workspace id is derived from the account: sha256("skriuw-sync-workspace-v1\0" + userId), computed in apps/sync/src/provision.ts.

  16. ADR-0045

    Rendered Mermaid fences

    The editable diagram block (spec) covers one Mermaid family: flowcharts its own parser accepts.

  17. ADR-0044

    Locked notes

    Users asked to put a PIN or passcode on a single note or a whole folder. Two very different features answer that request.

  18. ADR-0043

    End-to-end encrypted sync

    ADR-0026 replicates versioned domain operations through an ordered per-workspace log in a Cloudflare Worker and Durable Object, with large bodies and media…

  19. ADR-0042

    Modal Vim editing

    Writers who live in Vim asked for modal editing in both editors. ProseMirror has no Vim mode and the community packages cover a handful of motions at most,…

  20. ADR-0041

    Full-text content search over a rebuildable FTS5 projection

    Workspace search matched note titles from hydrated renderer state. Note bodies were indexed into an FTS5 virtual table, but the table stored raw Markdown, its…

  21. ADR-0041

    Cover gradients are named, not styled

    v1 let a note wear a built-in theme gradient as well as an uploaded image. v2 shipped only image covers, so a note that wanted colour at the top had to carry a…

  22. ADR-0041

    The compact shell is one column with sheets, a tab bar, and touch-owned gestures

    The workspace shell is a four-track grid: rail, tree, editor, inspector. On a phone the first three already exceed the viewport and the inspector renders off…

  23. ADR-0040

    The browser build is an installable shell that never caches workspace data

    The browser build is deployed under /app/ and is the only way to run Skriuw on a phone.

  24. ADR-0040

    An AI run is visible work, steered from the note

    ADR-0036 moved a text result out of a modal and into the note. Three things it left alone turned out to be the rest of the same problem.

  25. ADR-0039

    Provider-agnostic voice transcription seam

    Voice dictation turns a microphone recording into Markdown the writer can insert. Speech-to-text differs from the completion seam in ADR-0033 in shape, not in…

  26. ADR-0038

    Personal template and saved-search preferences

    Personal note templates reference ordinary canonical notes. The workspace settings extension noteTemplateIds records at most 200 source IDs; it never…

  27. ADR-0037

    Automatic sync convergence

    ADR-0026 replicates versioned domain operations through an ordered per-workspace log and applies them through the same validation as local operations.

  28. ADR-0036

    AI text results are reviewed in place, not in a modal

    An editor AI action produced a result the writer reviewed in a modal dialog: the proposed text in a scrolling box, an accept and a discard button, and the note…

  29. ADR-0035

    The note annotation layer is versioned document data

    Skriuw v2 needs freehand annotation over a whole note — ink and simple shapes drawn across the text, including the margins outside the writing column, staying…

  30. ADR-0034

    Annotation anchors are document data, conversations are not

    A comment thread has two halves that want different homes. The anchor — which text is being commented on — only means anything relative to the document, and…

  31. ADR-0033

    Provider-agnostic AI completion seam

    AI features need one completion path before local or remote providers, settings, or editor actions are added.

  32. ADR-0032

    Task-shaped typing is explicit intent

    ADR 0031 forbids implicit promotion so imported Markdown and ordinary checklists cannot silently fill the workspace task index.

  33. ADR-0031

    Explicit task promotion

    The editor already preserves taskId and blockId attributes on checkitem nodes through JSON, DOM, Markdown, and history, but nothing durable stood behind them.

  34. ADR-0030

    Remote cover download

    Covers could only come from a local file or an asset already in the workspace. A user holding an image address had to download it by hand and then upload it.

  35. ADR-0029

    Stored video media

    The workspace blob store, AttachImage operations, and the media library were built exclusively for images (PNG, JPEG, GIF, WebP).

  36. ADR-0028

    Browser sync runs the native coordinator logic inside the storage worker

    The browser runtime (ADR-0027) is local-only: the OPFS-backed SQLite worker has no sync, checkpoint, or hydration path, while the desktop coordinator…

  37. ADR-0027

    Browser SQLite uses a worker-owned OPFS SAH pool

    The browser runtime needs the same canonical SQLite behavior as desktop while keeping database, migration, and filesystem work off the renderer thread.

  38. ADR-0026

    Optional cloud operation replication

    Skriuw v2 must support an independent browser product and optional multi-device synchronization without making the existing desktop application…

  39. ADR-0025

    Embedded diagrams use a structured local model

    Skriuw needs diagrams that can be created from readable syntax and edited by pointer or keyboard inside a note.

  40. ADR-0024

    Previewed and atomic provider import

    Provider exports contain more than Markdown. They may carry folders, timestamps, tags, typed properties, local assets, provider-specific links, and unsupported…

  41. ADR-0023

    Lossless and reference-safe Markdown transfer

    Markdown is both a portable interchange format and the readable projection stored beside each structured document.

  42. ADR-0022

    Import into the Skriuw monorepo as the v2 linesuperseded

    This codebase started life as remcostoeten/skriuw-standalone: a ground-up rebuild of Skriuw, re-architected for performance from the first commit.

  43. ADR-0021

    Tabs and split view

    The product ships with one active note and one persistent ProseMirror editor host by deliberate decision (ADR-0020): "one persistent direct ProseMirror view"…

  44. ADR-0020

    UI architecture selection

    ADR-0004 deferred every UI and editor decision until measured evidence existed. The UI architecture gate in TODO.md required benchmarking editor candidates,…

  45. ADR-0019

    Archive compatibility fixtures

    WorkspaceArchive is the canonical interchange contract between desktop, recovery flows, and the future web runtime (ADR-0007).

  46. ADR-0018

    Read-only Git history integrity and cache rebuild

    Git history is an asynchronous projection of SQLite document revisions. Cached history headers can be rebuilt, but rebuilding from malformed Git state could…

  47. ADR-0017

    Verified live database swap

    Verified restore intentionally creates a new database path. Replacing the canonical desktop database requires coordination with the serialized runtime:…

  48. ADR-0016

    Deterministic operation-sequence scale fixtures

    The performance contract requires 1,000-note and 5,000-note workspaces before any UI benchmark can run, and the future web runtime must replay the same…

  49. ADR-0015

    Scheduled backup rotation

    ADR-0008 defines how to create and verify one native SQLite backup, but it does not define when periodic recovery points are due, how many survive, how they…

  50. ADR-0014

    Bounded failure diagnostics

    Runtime, storage, history, backup, recovery, and integrity failures currently surface through unrelated error enums and broad backend strings.

  51. ADR-0013

    Versioned settings and note metadata

    Settings were untyped SetSetting key/value rows in appstate. Nothing defined which settings exist, their defaults, their compatibility across versions, or…

  52. ADR-0012

    Lossless save batching

    Every submitted document save currently opens and commits an independent SQLite transaction.

  53. ADR-0011

    Graceful storage runtime shutdown

    WorkspaceRuntime spawned a detached storage worker with no lifecycle contract. Nothing rejected new work during teardown, nothing guaranteed accepted requests…

  54. ADR-0010

    Backend-owned node ranking

    Tree callers currently submit durable raw integer ranks. That leaks storage mechanics into UI code, permits accidental ties, and provides no recovery when…

  55. ADR-0009

    Subtree trash and permanent purge

    A tree operation on a folder affects the user's view of its complete subtree. Marking only the selected row as deleted without defining inherited availability…

  56. ADR-0008

    Verified native SQLite backups

    The desktop database uses WAL mode. Copying only the main database file can omit committed WAL content or produce an inconsistent recovery artifact.

  57. ADR-0007

    Portable workspace archive

    Users need export, import, recovery, and migration between desktop and a future web runtime.

  58. ADR-0006

    Native Git history materializer

    Desktop history needs durable Markdown diffs without requiring users to install Git and without introducing filesystem or native-library dependencies into…

  59. ADR-0005

    Asynchronous Git history

    Users need note history. Git offers durable Markdown diffs but filesystem writes and repository operations cannot enter editing or navigation paths.

  60. ADR-0004

    Defer UI and editor selection

    Framework popularity and bundle size do not prove post-startup latency. Editor DOM work is expected to dominate note switching and typing.

  61. ADR-0003

    Operation protocol and runtime adapters

    Desktop uses native SQLite. Future web may use SQLite WASM. UI behavior must not import Tauri or database details.

  62. ADR-0002

    SQLite is canonical

    Markdown files are portable but make rich-editor round trips, tree metadata, atomic multi-record writes, search indexing, and crash recovery more complex.

  63. ADR-0001

    Standalone local-first product

    Desktop ships first. Notes must remain usable without accounts, server availability, or network connectivity. A later web runtime may exist.

free · open source · no account

The decisions are public. So is the app.

Open the browser build and see what these records add up to. Nothing to install, no account.