@@ -4,204 +4,6 @@ Status: draft 0.40 · 2026-09-26
44Working name: not chosen yet. This document uses `notes` as the binary name; rename freely.
55Language: Rust · TUI: ratatui · Sync: Syncthing · History: file versioning on one node
66
7−Changes in 0.40: one spelling of task state. A block's state is the checkbox on its own
8−title line, like any node's; `todo:` is gone (read on legacy files, migrated on the next
9−toggle or `check --fix`), so `rg '\[ \]'` is the whole open-task list (§4.5, §8). Block
10−files keep their names when titles change; `check --fix` renames on request (§6.4). A block
11−file's later column-0 lines are adopted by its root instead of making it read-only (§4.9).
12−Verbs track nodes by key — titles plus ordinals among same-titled siblings — never by title
13−path (§3.4). Undo records exactly the files an operation touched and refuses if one changed
14−since (§10.11). Text after a child node is always preceded by a blank line (§4.2), and a
15−heading embed's level is checked against its position (§4.7). §3.1 states what the ordering
16−rule costs.
17−
18−Changes in 0.39: a node's children are an ordered list of **text children** and **child
19−nodes**, interleaved as they are in the file; the body is just the leading text (§3.1, §3.3).
20−Children obey one ordering rule, `(text | item)* section*`, because Markdown cannot close a
21−heading: every verb that places a node keeps it, and `~` moves the node it respells to the
22−boundary between items and sections instead of silently re-parenting its siblings (§3.1,
23−§10.3). Text children are not outline rows and stay where they are when nodes around them
24−move. A section block's embed is a **heading embed**, `## ![[id]]`, so it keeps its place
25−among section siblings (§4.7). Merge compares a node's text children as one field and places
26−insertions by the ordering rule (§12.4).
27−
28−Changes in 0.38: no external editor in 1.0. `E`, the inline-frontmatter spelling, the
29−`inline` render mode and `$EDITOR` are gone; the built-in editor is the only editor (§10.6,
30−§17). Frontmatter never appears as text anywhere.
31−
32−Changes in 0.37: `E` is scoped to the selected node and replaces its subtree wholesale on
33−exit. The text handed to `$EDITOR` carries every nested block's frontmatter **inline**, as a
34−`---` block under its title line, `id` included, so blocks come back matched exactly by id;
35−no line diff, no heuristics (§4.4, §10.6). `e` is unchanged.
36−
37−Changes in 0.36: editing is continuous. The built-in editor is one text over the resolved
38−subtree with no locked lines, no dimming and no commit key: every line carries its owning
39−block invisibly, edits apply to whichever block the cursor is in, and blocks are saved
40−automatically when the cursor leaves them, after a short pause, and on exit (§5.2, §10.6).
41−The *make block* / *cut* distinction is not visible while typing.
42−
43−Changes in 0.35: vocabulary. *Document*, *part* and *cut* were one concept and are now
44−**block**: a node with an id, a file and properties, edited alone. *Edge* is **embed**,
45−which is what `![[id]]` is. The *document pane* is the *reading pane*. Storage sections
46−still say "file" where they mean bytes on disk.
47−
48−Changes in 0.34: every edit changes exactly one file. The editor still shows the whole
49−resolved subtree, but only the lines owned by one **part** — the file the cursor node lives
50−in — are editable; the rest is context, shown but locked, and the status line names the
51−part. Splice is single-file again; the multi-file distributor is gone (§5.2, §10.6).
52−
53−Changes in 0.33: properties never appear in text. The resolved rendering the user reads and
54−edits has no frontmatter and no property blocks; properties are edited in a form (`a`,
55−§10.6) and shown as a dimmed header in the document pane. Splice never touches
56−frontmatter.
57−
58−Changes in 0.32: files are invisible when editing. The user edits a slice of one large
59−document: `e`/`E` open the **resolved** subtree — documents inlined, no `![[id]]`, no ids —
60−with each node's properties shown as a `---` block under its title line (§4.4). Splice
61−parses the result and distributes it back to whichever files own the text, cutting,
62−moving and trashing files as the text requires (§5.2). Files are storage, not UI.
63−
64−Changes in 0.31: one editing model. `e` opens the selected subtree's Markdown —
65−`render(cursor, 1, false)`, frontmatter included — in an editor and splices it back; `E`
66−does the same in `$EDITOR`. Title editing, the block editor and the property editor are
67−gone: a title, a property, a body are all just text in the subtree (§10.6).
68−
69−Changes in 0.30: the `:` command line is a command palette — a fuzzy picker over every
70−action, showing its key, prompting for arguments after selection (§10.9). No command syntax
71−to learn or type.
72−
73−Changes in 0.29: frontmatter is text. No value types, no `tags` key, no `--set`/`--due` on
74−capture, no relative date forms. The app knows five keys — `id`, `todo`, `due`, `done`,
75−`conflict` — reads them as strings, validates the two dates as ISO when it writes them, and
76−preserves every other line verbatim (§3.2, §4.4).
77−
78−Changes in 0.28: the query language, saved views, query blocks, the `v` picker, result
79−views, `notes query` and `--json` are out of 1.0 (§17). `query` fences are reserved. The
80−fresh vault is `# Inbox` alone. The filter box (§10.5) is the only search.
81−
82−Changes in 0.27: no config file. `config.toml` and its seven keys are gone; the vault comes
83−from `$NOTES_VAULT` or the working directory, the editor from `$EDITOR`, and the rest is
84−fixed or a session toggle (`zd`, `zr`). The trash is the only thing outside the vault (§14).
85−
86−Changes in 0.26: the CLI is six commands: `notes`, `capture`, `query`, `check [--fix]`,
87−`merge`, `trash`. `init`, `config`, `view`, `ls`, `set`, `unset`, `cut`, `archive`,
88−`canonicalize` and `adopt` are gone; the TUI does each of them, and `check --fix` absorbs
89−canonicalize (§13). Foreign `.md` files can no longer be adopted; paste their text instead.
90−
91−Changes in 0.25: more removals. The cancelled task state (`[-]`, `todo: cancelled`,
92−`cancelled:`, `X`) and the `priority` and `repeat` keys are gone. No tabs, no `:sort`, no
93−create-from-filter-box, no `notes inbox` / `props` / `id`, no `keys.*` rebinding or theme,
94−no `Ctrl-w`. The `Waiting` default view is gone and the `Inbox` view is now `Queue`.
95−`notes render`, `:export` and the `--plain` lowering are removed: there is no export in 1.0
96−(§17); `render` remains an internal function.
97−
98−Changes in 0.24: seven removals. One edge shape, `![[id]]`, and a document's file starts
99−with the node as spelled — no more `#`-always rule (§4.7, §4.9). No in-session three-way
100−merge: a splice that finds its span changed writes a conflict document like any other
101−conflict (§5.2). No fuzzy title matching in merge (§12.4). Files without a valid `id` are
102−ignored, not "unmanaged" (§4.1). Archive is plain refile under `Archive` (§6.5). No
103−`--as dir/`: the vault is flat and prefixes are unique vault-wide (§6.4). No `conflicts/`
104−directory and no `conflict_with` key: conflict copies are ordinary documents marked
105−`conflict:`, stitched in next to ours (§12.4).
106−
107−Changes in 0.23: no cache and no per-device state. The index is rebuilt from the vault on
108−every start; there are no shadow copies, so sync-conflict merging is two-way (§11.3, §12.3).
109−The in-session splice conflict keeps its three-way base in memory.
110−
111−Changes in 0.22: `uncut` removed. A cut is permanent; a document stays a file until deleted.
112−Conflict resolution copies text instead of uncutting (§12.5).
113−
114−Changes in 0.21: a document's task state is the frontmatter key `todo: open | done |
115−cancelled`, not a checkbox on its title line. Checkboxes remain the syntax for nodes that
116−are not files. Cut and uncut convert between the two (§4.5, §8).
117−
118−Changes in 0.20: the separator between id prefix and name in filenames is `~`:
119−`racfer~order-new-switch.md`. Words inside the prefix stay `-`-joined.
120−
121−Changes in 0.19: filename prefixes are unique on their own, ignoring the title: no two files
122−in a directory share a prefix, whatever their names (§6.4).
123−
124−Changes in 0.18: ids are 64 bits, four `@p` words (`racfer-hattes-dozzod-binwes`). Filenames
125−start with the shortest prefix of the id — one word by default — that is unique in the
126−directory, and grow a word at a time when a collision is found, locally or at merge (§6.4,
127−§12.2). The `-2` suffix is gone.
128−
129−Changes in 0.17: filenames are `<word>-<name>.md`, where `<word>` is the first word of the
130−id (`racfer-order-new-switch.md`). Same-title documents no longer collide across devices
131−except at 1 in 65,536; the merge engine treats an id mismatch as a name collision, not a
132−conflict (§6.4, §12.2).
133−
134−Changes in 0.16: `@key(value)` annotations removed. All metadata is frontmatter again, so
135−only documents carry it: `done:` and `cancelled:` are stamped on task documents, inline
136−tasks record state only, and nothing records creation time. Conflict copies are documents
137−in `conflicts/` again, with `conflict:` frontmatter. `@` appears only in the query language.
138−
139−Changes in 0.15: the "no syntax of our own" restriction is lifted (§1). Consequences:
140−one structural node kind with two spellings, either nestable under either (§3.1);
141−heading levels unbounded, `§5.3` level overflow gone; any node can be a task, headings
142−included (§4.5); a document's task state lives on its own title line, edges carry none
143−(§4.7, §4.9); the app stamps `@created`, `@done`, `@cancelled` as title-line annotations on
144−any node (§3.2); the id moves from the filename into `id:` frontmatter, filenames are plain
145−slugs, edges are `![[id]]` (§3.4, §6.4); `|` is allowed in titles; merge conflicts are
146−inline `@conflict` siblings, `conflicts/` is gone (§12.4). `notes render --plain` lowers
147−the format to standard Markdown for export (§5.1).
148−
149−Changes in 0.14: `[[wiki-links]]` between nodes removed from 1.0 — no link syntax, resolution,
150−rename rewriting, backlinks or tombstones. `[[…]]` in titles and bodies is opaque text,
151−preserved verbatim and reserved (§4.6, §17). Edges (`![[id-name]]`) and external
152−`[text](url)` links are unchanged.
153−
154−Changes in 0.13: capture appends under a `## <today>` child of `Inbox`, created on demand.
155−Fixed behaviour, not a setting; the day title is ISO `YYYY-MM-DD`.
156−
157−Changes in 0.12: every path component the app writes is lowercase — file names, directory
158−names (including `--as`), temp and trash names. Titles keep their case; resolution is
159−case-insensitive.
160−
161−Changes in 0.11: no vault settings at all. Capture always goes to the level-1 section titled
162−`Inbox`, created if missing. `root.md` has no frontmatter in a fresh vault.
163−
164−Changes in 0.10: `done_precision` and `conflicts` removed. `done:` records a date; conflict
165−documents live in `conflicts/`. `inbox` is the only vault setting.
166−
167−Changes in 0.9: `archive` and `:archive-done` removed — done items stay where they are,
168−a display toggle hides them, and `:clear-done` trashes them when a list is finished.
169−(An `archive` section as a plain refile target returns later — see §6.5.)
170−`suggest_bytes` removed — the app never suggests cuts. Three vault settings remain:
171−`inbox`, `done_precision`, `conflicts`.
172−
173−Changes in 0.8: `capture` renamed `inbox` and is a plain link target (no date template);
174−`children: files` removed, so there are no section settings and no derived directories;
175−`cut`, `rename`, `transliterate` and `id_words` removed — cuts are property-triggered or
176−manual, filenames follow titles, names keep Unicode, ids are two words. Five vault settings
177−remain: `inbox`, `archive`, `done_precision`, `conflicts`, `suggest_bytes`.
178−
179−Changes in 0.7: `dir` and `sort` removed. The only section setting is `children: files`;
180−its files go in a directory named after the section. New children are always appended.
181−
182−Changes in 0.6: `config.toml` is gone. Vault settings are `root.md`'s frontmatter; section
183−settings (`children`) are the section's own frontmatter; saved views are query
184−blocks. A fresh vault is initialised with a `root.md` that lists every setting at its default,
185−commented. Only an optional, device-local file for UI preferences remains.
186−
187−Changes in 0.5: the journal is no longer a concept. Capture appends to a configurable,
188−date-templated target (default `Inbox/{date}`), and "children of this section are always
189−files" is a general `[[cut.auto]]` rule. Journal days become ordinary documents; the id-less
190−filename shape and the date resolution step are gone.
191−
192−Changes in 0.4: ids are two-word phonemic names in Urbit's `@p` syllable scheme
193−(`racfer-hattes`, 32 bits) instead of 8-character base32.
194−
195−Changes in 0.3: document files are named `<id>-<name>.md`, where the id is an 8-character
196−random base32 string and the name is a slug of the title. Links and edges resolve by id, so
197−they survive renames and stale rewrites; the name is decoration for humans and other tools.
198−
199−Changes in 0.2: all inline attribute syntax (`@key(value)`) removed. Properties exist only as
200−YAML frontmatter of a file, so a node that needs properties becomes a file ("document").
201−Items can be cut into documents; their checkbox stays on the edge in the parent list.
202−`@id` removed; the file slug is the identity. Merge conflicts are stored as documents in
203−`conflicts/`. Task-state syntax `[ ]`, `[x]`, `[-]` is unchanged.
204−
2057---
2068
2079## 1. Purpose and principles
@@ -356,7 +158,6 @@ Reserved keys (the app assigns semantics; users may still read/write them by han
356158| Key | Value | Meaning |
357159|---|---|---|
358160| `id` | four `@p` words | The block's identity (§3.4). Present on every managed file; never on `root.md`. |
359−| `todo` | `open` \| `done` | **Legacy.** Before 0.40 it held a block's task state. Read only when the block's title line has no checkbox, reported by `notes check`, and removed on the next toggle or `check --fix`, which write the checkbox instead (§4.5). The app never writes it. |
360161| `due` | `YYYY-MM-DD` | Task due date; shown in the outline. |
361162| `done` | `YYYY-MM-DD` | Written when a task block is checked; removed when unchecked. |
362163| `conflict` | `<device> <timestamp>` | Marks a "theirs" copy written by the merge engine (§12.4). |
@@ -542,8 +343,7 @@ Inside the app, frontmatter is storage: the reading pane shows a block's propert
542343dimmed header computed from the index, the property editor (`a`, §10.6) changes them, and
543344the built-in editor's text (§5.1, `resolve_blocks = true`) contains none.
544345
545−Frontmatter never appears as text to the user. (An inline `---`-under-the-title spelling
546−was designed for an external editor and is set aside with it, §17.)
346+Frontmatter never appears as text to the user.
547347
548348### 4.5 Tasks
549349
@@ -569,9 +369,8 @@ There is no cancelled state. A task that will never be done is either checked of
569369deleted.
570370
571371Embeds carry no state: the checkbox travels with the title line into the block's file when
572−it is made (§6.1). A legacy `todo:` key (§3.2) is read as the state when the title line has
573−no checkbox; if both are present the checkbox wins. A task section has its own state *and*
574−the derived count of its subtree. See §8.
372+it is made (§6.1). A task section has its own state *and* the derived count of its subtree.
373+See §8.
575374
576375### 4.6 Links
577376
@@ -801,7 +600,7 @@ Edge cases follow from the tags, not from rules:
801600### 5.3 Levels
802601
803602Heading levels are unbounded (§3.1), so splice never changes a node's spelling and never
804−demotes anything. The level-overflow rule of earlier drafts is gone.
603+demotes anything.
805604
806605### 5.4 One function, three uses
807606
@@ -1012,8 +811,8 @@ Out of scope for 1.0. Nothing is reserved for it.
1012811## 9. Query language
1013812
1014813Not in 1.0. Search is the filter box (§10.5): fuzzy title match plus full-text match over
1015−the whole vault, live, no syntax. A query language with saved views was designed and set
1016−aside (§17, open decision 16); the ```` ```query ```` fence is reserved for it (§4.8).
814+the whole vault, live, no syntax. A query language is future work (§17, §19 decision 16); the
815+```` ```query ```` fence is reserved for it (§4.8).
1017816
1018817---
1019818
@@ -1084,7 +883,7 @@ aside (§17, open decision 16); the ```` ```query ```` fence is reserved for it
1084883| `r` | refile: fuzzy-pick a destination; `Ctrl-Enter` = as first child |
1085884| `c` / `C` | capture to the inbox as bullet / as task |
1086885| `/` | filter box (§10.5) |
1087−| `:` | command palette (§10.9); `?` help |
886+| `:` | command palette (§10.8); `?` help |
1088887| `u` / `U` | undo / redo |
1089888| `q` | quit (nothing is ever unsaved in normal mode) |
1090889
@@ -1128,7 +927,7 @@ app keeps track. Blocks are saved on their own:
1128927The status line shows the title of the block the cursor is in, dimmed, and a dot while
1129928something is unsaved — the only two hints that blocks exist. `Ctrl-c` discards changes made
1130929since the last save. Undo inside the editor is the editor's own; each automatic save is one
1131−entry in the session op log (§10.11). The box is not a Markdown editor and stays one.
930+entry in the session op log (§10.10). The box is not a Markdown editor and stays one.
1132931
1133932Properties are not text. `a` opens the **property editor**: a small form listing the
1134933node's keys and values, where you add, change and delete entries. `due` and `done` accept
@@ -1142,11 +941,7 @@ editing are the same gesture. `x`, `t`, `~`, `>`/`<`, `J`/`K`, `r` and `d` are t
1142941structural verbs; they exist because toggling a checkbox should not require the editor,
1143942and each saves the editor first.
1144943
1145−### 10.7 (removed)
1146−
1147−Result views went with the query language (§9).
1148−
1149−### 10.8 Conflict view
944+### 10.7 Conflict view
1150945
1151946Entered when a `.sync-conflict-*` file is detected or a splice hits a changed span. Shows
1152947each conflict pair (ours in place, the `conflict:` block right after it) side by side; `o` keeps ours,
@@ -1154,7 +949,7 @@ each conflict pair (ours in place, the `conflict:` block right after it) side by
1154949Unresolved pairs remain as `conflict:` blocks and stay listed in the status
1155950line until resolved (§12.5).
1156951
1157−### 10.9 Command palette
952+### 10.8 Command palette
1158953
1159954`:` opens a popup listing every action the TUI has, filtered live by fuzzy match (nucleo)
1160955on the action's name and description, each row showing its key binding if it has one.
@@ -1168,14 +963,14 @@ action reachable by key is in the palette under a readable name (*make block*,
1168963*canonicalize*, *check*, *merge*. `?` is the same popup filtered to show keys, so help and
1169964palette are one thing.
1170965
1171−### 10.10 Markdown styling in the reading pane
966+### 10.9 Markdown styling in the reading pane
1172967
1173968Line-based, not a full renderer: headings by level, task glyphs (`☐ ☑`), resolved blocks'
1174969properties dimmed at the end of the line, underlined external links, styled code fences,
1175970`**bold**` / `*em*` / `` `code` `` inline, blockquote bars. Raw text is never hidden;
1176971`zr` shows exact source, frontmatter included.
1177972
1178−### 10.11 Undo, redo, saving
973+### 10.10 Undo, redo, saving
1179974
1180975Every mutation is an operation with an inverse (span edits, file create/move/delete,
1181976including making blocks). The session op log powers `u` / `U`. Outline verbs write
@@ -1313,7 +1108,7 @@ algorithm is deterministic and idempotent.
13131108
13141109### 12.5 Resolution
13151110
1316−The conflict view (§10.8) lists every `conflict:` block, each shown against the sibling
1111+The conflict view (§10.7) lists every `conflict:` block, each shown against the sibling
13171112before it, and the status line counts them. Resolving a pair:
13181113
13191114- **keep ours** — delete the conflict block and its embed (to trash);
@@ -1355,16 +1150,16 @@ recovery session needs. Everything else is a TUI verb.
13551150
13561151## 14. Settings
13571152
1358−There are no vault settings. Everything that would have been one is either fixed behaviour
1359−or content: the inbox is the section titled `Inbox` (§7);
1153+There are no vault settings. Everything that could be one is either fixed behaviour or
1154+content: the inbox is the section titled `Inbox` (§7);
13601155filenames are an id prefix plus the title; names keep Unicode; ids are four words in
13611156frontmatter (§6.4); making blocks
13621157are property-triggered or manual only; `done:` records a date; conflict copies are
13631158blocks marked `conflict:`. Each was a knob nobody needs to agree on with a file. Two vaults that
13641159contain the same Markdown behave identically.
13651160
1366−There are no device settings either. The app reads no file outside the vault. What used to
1367−be configuration is now:
1161+There are no device settings either. The app reads no file outside the vault. What other
1162+tools keep in configuration is:
13681163
13691164- the vault: `--vault PATH`, else `$NOTES_VAULT`, else the nearest ancestor of `$PWD`
13701165 containing `root.md`, else `~/notes`;
@@ -1516,9 +1311,7 @@ gets wrong. What other tools see:
15161311Encryption; CRDT / operation-log sync; a mobile client (the file format is its contract);
15171312a query language, saved views and `--json` output (the ```` ```query ```` fence is reserved); attachment management beyond ignoring `assets/`; full Markdown
15181313rendering or WYSIWYG; plugins; task recurrence; spaced repetition; whiteboards; multiple
1519−vaults open at once; general transclusion; an external `$EDITOR` handoff (designed:
1520−resolved subtree with frontmatter inline under each block's title, ids included, replaced
1521−wholesale on exit); properties on non-blocks; export or lowering
1314+vaults open at once; general transclusion; an external `$EDITOR` handoff; properties on non-blocks; export or lowering
15221315to standard Markdown (the four non-standard forms of §4.2 are the whole gap); a cancelled
15231316task state; wiki-links between nodes and backlinks
15241317(`[[…]]` is reserved, §4.6); rendering the format correctly in third-party editors.
@@ -1539,7 +1332,7 @@ task state; wiki-links between nodes and backlinks
15391332
15401333---
15411334
1542−## 19. Open decisions
1335+## 19. Decisions
15431336
154413371. **Name.** Binary `notes` is a placeholder.
154513382. **Dated inbox, ISO titles, fixed.** Capture creates `## YYYY-MM-DD` under `Inbox`. There
@@ -1548,85 +1341,61 @@ task state; wiki-links between nodes and backlinks
154813413. **Filenames are named once.** A title change does not rename the file: renames sync as
15491342 delete-plus-create and race with edits on other devices. The id prefix identifies the
15501343 file; the name is a hint that `notes check --fix` refreshes on request.
1551−3b. **Id format.** Four-word `@p` names (64 bits). Two words (32 bits) were enough for
1552− identity but left the one-word filename prefix with only 16 bits of room to grow; four
1553− words make the id collision-free in practice and give the prefix three words of slack.
1554− Chosen for being pronounceable, typeable from memory, and self-validating against the
1555− syllable tables; nobody is expected to type all four.
1556−4. **Task sections.** Any node can be a task, so a project heading can be checked off. The
1344+4. **Id format.** Four-word `@p` names (64 bits): collision-free in practice, with three words
1345+ of slack for the filename prefix to grow into. Pronounceable, typeable from memory, and
1346+ self-validating against the syllable tables; nobody is expected to type all four.
1347+5. **Task sections.** Any node can be a task, so a project heading can be checked off. The
15571348 derived count is still shown beside it; there is no roll-up in either direction (§8.3).
1558−4b. **One spelling of task state.** The checkbox, for every node. Until 0.39 blocks used
1559− `todo:` in frontmatter instead; that hid block tasks from `rg '\[ \]'` and cost a
1560− conversion every time a task became a block. All-frontmatter was never an option (it
1561− would make every task a file). A block keeps one thing a plain task lacks: `done:`.
1562−5. **Two task states.** Open and done. Cancelled was removed: it was a third value in every
1563− table, a second date key, and a key binding, for a distinction between "done" and
1564− "won't do" that a deleted line or a done line expresses well enough. `[-]` is read as
1565− done for old vaults.
1566−6. **No un-block.** Earlier drafts had an inverse of making a block that dropped the frontmatter. Removed:
1567− a verb whose defining feature is discarding data is a footgun, and the manual route
1568− (yank, paste, delete) makes the loss explicit. Revisit only if vaults fill with
1569− blocks nobody wanted.
1570−7. **No export.** `notes render` and the `--plain` lowering were removed for 1.0. The
1571− resolved render is now only what the reading pane reads; a standalone-Markdown exporter
1572− is a later feature with a known scope (§4.2's four forms).
1573−8. **No fuzzy matching in merge.** A node retitled on one device and edited on another
1574− comes out of a merge as two nodes. The fuzzy title match that would have paired them
1575− needed a tunable threshold and could pair the wrong nodes; a duplicate is cheaper to
1576− fix than a wrong pairing, so the step was removed.
1577−8b. **Two-way merge, no cache.** Shadow copies would have made sync merges three-way and
1578− resolved most differences automatically; they were the only per-device state and were
1579− removed with it (§11.3). Sync conflicts now produce a conflict pair for every differing
1580− field. The mitigation is structural: keep concurrently-edited things in separate files
1581− (§12.1), so conflicts are small and rare. If they turn out to be neither, a per-device
1582− base is the thing to bring back.
1583−9. **Text is edited as text, properties as a form.** Earlier drafts had a title editor and
1584− a block editor beside an external-editor handoff; those collapsed into one subtree edit,
1585− and the external handoff was then dropped from 1.0 (§17). Properties briefly appeared in
1586− the text as `---` blocks and were taken out again: frontmatter is a storage format, and
1587− showing it would surface files. The property editor is the one non-text edit. The
1588− built-in editor is a text box; if it wants to become a Markdown editor, stop.
1589−10. **Inbox by title.** Capture finds the inbox by the title `Inbox`. Renaming it means the
1590− next capture creates a new one. A hidden marker property was the alternative and would
1591− have been the last setting.
1592−10b. **No config file.** Seven presentation keys, each already available from the environment
1593− or replaceable by a key binding, were not worth a file format, a lookup order, and a
1594− `notes config` command. If a real per-device need appears (a colour-blind palette, say)
1595− it can come back as one environment variable.
1596−11. **Windows.** Slugs and atomic writes are Windows-safe by design; nothing else is tested.
1597−12. **No links in 1.0.** Storing links by id, displaying the live title, and rewriting labels
1598− on rename were all designed and then cut for the first implementation. Embeds already
1599− prove the id machinery; links can return on top of it without changing the file format,
1600− which is why `[[…]]` is reserved rather than free.
1601−13. **No per-node timestamps.** Title-line annotations (`@done(…)`, `@created(…)`) were
1602− tried in 0.15 and removed: one metadata mechanism is worth more than inline completion
1603− dates. An inline task that needs a date becomes a block; the day section is the
1604− only creation stamp anything else gets.
1605−13b. **Flat vault.** `--as dir/` was removed; the app never creates a directory and ignores
1606− any it finds. Hierarchy is embeds, and one place for files keeps prefixes unique
1607− vault-wide with no per-directory rule.
1608−14. **Prefix collisions.** Two blocks whose ids share a first word are `racfer~notes.md`
1349+6. **One spelling of task state.** The checkbox, for every node, so `rg '\[ \]'` finds every
1350+ open task and making a block never converts anything. Frontmatter holds only what a
1351+ checkbox cannot: `done:`.
1352+7. **Two task states.** Open and done. "Won't do" is a deleted line or a done line; a third
1353+ state would cost a value in every table, a second date key and a key binding. `[-]` is
1354+ read as done.
1355+8. **No un-block.** There is no inverse of making a block: it would have to discard the
1356+ frontmatter, and a verb whose defining feature is discarding data is a footgun. The
1357+ manual route (yank, paste, delete) makes the loss explicit.
1358+9. **No export.** The resolved render is what the reading pane shows; a standalone-Markdown
1359+ exporter is future work with a known scope (§4.2's four forms).
1360+10. **No fuzzy matching in merge.** A node retitled on one device and edited on another
1361+ comes out of a merge as two nodes. A fuzzy title match would need a tunable threshold and
1362+ could pair the wrong nodes; a duplicate is cheaper to fix than a wrong pairing.
1363+11. **Two-way merge, no cache.** A per-device base copy would make sync merges three-way,
1364+ but it would be the only per-device state (§11.3). Sync conflicts therefore produce a
1365+ conflict pair for every differing field; the mitigation is structural — keep
1366+ concurrently-edited things in separate files (§12.1), so conflicts are small and rare.
1367+12. **Text is edited as text, properties as a form.** One subtree edit in a text box covers
1368+ titles, bodies and structure. Frontmatter is a storage format, and showing it would
1369+ surface files, so the property editor is the one non-text edit. The built-in editor is a
1370+ text box; if it wants to become a Markdown editor, stop.
1371+13. **Inbox by title.** Capture finds the inbox by the title `Inbox`. Renaming it means the
1372+ next capture creates a new one. A hidden marker property would be the only setting.
1373+14. **No config file.** Presentation choices are fixed or session toggles; a config format, a
1374+ lookup order and a `notes config` command are not worth it. A real per-device need (a
1375+ colour-blind palette, say) would be one environment variable.
1376+15. **Windows.** Slugs and atomic writes are Windows-safe by design; nothing else is tested.
1377+16. **No links or query language in 1.0.** Embeds prove the id machinery, and links can be
1378+ built on it without changing the file format, which is why `[[…]]` is reserved rather
1379+ than free. The likely query shape is "everything is a key" (`due:..today`, text is
1380+ literal, `-` negates, `..` ranges); until then the filter box is the only search and the
1381+ `query` fence is reserved.
1382+17. **No per-node timestamps.** One metadata mechanism is worth more than inline annotations
1383+ such as `@done(…)`. An inline task that needs a date becomes a block; the day section is
1384+ the only creation stamp anything else gets.
1385+18. **Flat vault.** The app never creates a directory and ignores any it finds. Hierarchy is
1386+ embeds, and one place for files keeps prefixes unique vault-wide with no per-directory
1387+ rule.
1388+19. **Prefix collisions.** Two blocks whose ids share a first word are `racfer~notes.md`
16091389 and `racfer-wolsun~order-new-switch.md`, regardless of their titles; the prefix grows only
1610− as far as needed and never shrinks (§6.4). Uniqueness is judged on the prefix alone, not
1611− the whole filename, so the prefix is a complete address and titles can change freely.
1612− The cost is that roughly one file in 256 needs a second word from day one; that was
1613− judged cheaper than a rule that depends on titles. The full id was rejected as too long
1614− for a name, the bare slug as too collision-prone across devices, and a numeric `-2` as
1615− meaningless.
1616−17. **Ownership travels with lines.** Three other models were tried: distributing a
1617− multi-file edit back by re-matching nodes (needs heuristics and a prompt when they
1618− fail), showing nested blocks as placeholders (leaks files into the text), and locking
1619− every block but one (a seam the user has to work around). Tagging each buffer line with
1620− its block and saving blocks as the cursor leaves them needs no matching, shows no seam,
1621− and still writes each file from its own text. An external editor cannot carry tags;
1622− the design for one (frontmatter inline, ids included, subtree replaced on exit) is
1623− parked in §17.
1624−16. **No query language in 1.0.** Several syntaxes were sketched — boolean with `@key`, a
1625− search box with `is:` and `key:value`, and "everything is a key" (`todo:open
1626− due:..today`, text is literal, `-` negates, `..` ranges). The last is the likely
1627− shape when it returns. Until then the filter box is the only search and the `query`
1628− fence is reserved.
1629−15. **Third-party editors are readers, not editors.** Once the format owns syntax, Obsidian
1630− and friends stop being a safe place to restructure a vault. Editing a body paragraph
1631− there is still fine; moving headings is not. This is the price of §1 principle 2 and is
1632− accepted.
1390+ as far as needed and never shrinks (§6.4). Uniqueness is judged on the prefix alone, so
1391+ the prefix is a complete address and titles can change freely. Roughly one file in 256
1392+ needs a second word from day one, which is cheaper than any rule that depends on titles;
1393+ the full id is too long for a name, the bare slug too collision-prone across devices, and
1394+ a numeric `-2` meaningless.
1395+20. **Ownership travels with lines.** Each editor line is tagged with its block, and blocks
1396+ are saved as the cursor leaves them. That needs no re-matching of nodes after an edit,
1397+ shows no seam between files, and still writes each file from its own text. An external
1398+ editor cannot carry the tags, so there is none in 1.0 (§17).
1399+21. **Third-party editors are readers, not editors.** Once the format owns syntax, Obsidian
1400+ and friends are not a safe place to restructure a vault. Editing a paragraph there is
1401+ fine; moving headings is not. This is the price of §1 principle 2 and is accepted.