| 1 | # Snowbound |
| 2 | |
| 3 | Snowbound is a modern remake of OneNote 2010 that stays fully interoperable |
| 4 | with it. Notes are rich text on a free canvas, stored in OneNote's own `.one` |
| 5 | files, so Snowbound and OneNote 2010 can open the same notebook side by side. |
| 6 | A notebook is just a folder. Put it on an SMB share and several people can |
| 7 | edit it together from either app, with no cloud service involved. With headless |
| 8 | crates implementing the file format and a generic canvas renderer made with a |
| 9 | novel UI kit, each new platform port is extremely lightweight. |
| 10 | |
| 11 | ## Crates |
| 12 | |
| 13 | | Path | Owns | Depends on | |
| 14 | | --- | --- | --- | |
| 15 | | `crates/onestore` | The file format: revision stores (`.one`, `.onetoc2`), the page model, ops, the commit protocol. No network, no SQLite, no `unsafe`. | none | |
| 16 | | `crates/notebook` | From editor to disk or share: discovery, notebook structure, sessions, the SQLite replica, sync and merging, conflict pages, the embedded SMB client (feature `smb`), live presence between peers (feature `live`). | onestore, relay | |
| 17 | | `crates/relay` | `snowbound-relay`, the WebSocket relay Live Share meets through off the LAN, and the framing and notices its clients share with it. Sees only sealed frames. | none | |
| 18 | | `crates/draw` | The wgpu renderer that page and chrome both paint through, and the text-editing core (keys, chords, carets) they share. | none | |
| 19 | | `crates/canvas` | The page: editor, OneNote-faithful layout, page scene, interaction, the page's accessibility tree. | onestore, draw | |
| 20 | | `crates/ui` | The immediate-mode interface kit and OneNote's chrome controls. Knows nothing of notebooks. | draw | |
| 21 | | `crates/snowbound` | The desktop app: winit window, platform glue, sidebar, menus, templates. | all of the above | |
| 22 | | `crates/mobile`, `apps/ios` | A C surface over canvas and notebook, and the UIKit app built on it. | canvas, notebook, and below | |
| 23 | | `tools/`, `corpus/`, `fuzz/` | Lab harnesses (Python, PowerShell, AutoHotkey), the corpus of OneNote-verified files, and a separate cargo-fuzz workspace. | | |
| 24 | |
| 25 | Dependencies point from the apps toward the format, never back. The format |
| 26 | crate never learns about storage engines, networks or pixels. `canvas` emits |
| 27 | ops but never touches storage. `ui` never sees a notebook. The hosts are where |
| 28 | these pieces meet. |
| 29 | |
| 30 | ## Rules that matter most |
| 31 | |
| 32 | - **Edits are ops, and each edit appends one revision.** `onestore` and |
| 33 | `notebook` never recreate a whole page or section from a model. Only creating |
| 34 | a section or page, and opening a file, handle whole images. A design that |
| 35 | diffs whole pages to save them is the wrong design. |
| 36 | - **Write what the spec requires and what OneNote writes; read tolerantly.** |
| 37 | Emit every property MS-ONESTORE and MS-ONE require (even where OneNote |
| 38 | tolerates an omission), plus what OneNote itself stores. Readers accept |
| 39 | whatever is out there. |
| 40 | - **OneNote 2010 is the reference.** When behaviour is in question, observe it |
| 41 | in the Windows 7 lab (`tools/w7`) before deciding. A storage feature is done |
| 42 | when a file Snowbound wrote cold-opens in a fresh OneNote and reads back as |
| 43 | intended ([testing](arc/testing.md)). |
| 44 | - **Disposable copies only.** Never point the app, a replay script or a lab |
| 45 | harness at an original notebook. |
| 46 | |
| 47 | ## Sync in one breath |
| 48 | |
| 49 | A `.one` file is a revision store. Every client, OneNote included, commits by |
| 50 | appending a revision and then rewriting the 1024-byte header, which makes the |
| 51 | header plus the file length a cheap *stamp* of the committed state. Snowbound |
| 52 | queues edits as ops in a local SQLite replica. A background thread checks the |
| 53 | stamp when an edit is queued or the share reports a change (SMB change |
| 54 | notifications or the OS file watcher, as OneNote does; it polls only where |
| 55 | nothing can watch). If the stamp is unchanged, it publishes the queued batch as one |
| 56 | appended revision. If it has changed, it reads the file once and replays the |
| 57 | queue on top. Where an op can't merge, the result is what OneNote 2010 makes: a |
| 58 | read-only conflict page under the page. OneNote coordinates writers through |
| 59 | share modes and one-byte locks on the section file itself. These are special SMB |
| 60 | protocols that only Windows supports, so Snowbound carries its own SMB client |
| 61 | that can properly issue them. Offline is just a sync step that fails: the queue |
| 62 | waits and publishes later. [More in the sync essay.](arc/sync.md) |
| 63 | |
| 64 | ## Architecture notes |
| 65 | |
| 66 | - [The file format and `onestore`](arc/file-format.md): revision stores, |
| 67 | object spaces, transactions, and what "append one revision" means. |
| 68 | - [The data layer and sync](arc/sync.md): ops, sessions, the replica, |
| 69 | publishing, merging, conflict pages, SMB and locking, offline. |
| 70 | - [The page: editor and canvas](arc/canvas.md): layout, OneNote-faithful |
| 71 | geometry, the page view, accessibility. |
| 72 | - [The interface kit and the renderer](arc/ui.md): immediate mode, |
| 73 | custom drawing, the OneNote shell and its motion. |
| 74 | - [Platforms](arc/platforms.md): macOS, Linux, and iOS with UIKit around the |
| 75 | canvas. |
| 76 | - [Testing, and why the code can be trusted](arc/testing.md): the native |
| 77 | lab, oracles, failure injection, fuzzing, and the two test tiers. |
| 78 | |
| 79 | The crate READMEs ([onestore](crates/onestore/README.md), |
| 80 | [notebook](crates/notebook/README.md)) are the API references. |
| 81 | [tools/TESTING.md](tools/TESTING.md) lists the test lanes. |
| 82 | |
| 83 | ## Working here |
| 84 | |
| 85 | ```sh |
| 86 | cargo test --workspace --all-features |
| 87 | cargo clippy --workspace --all-targets --all-features -- -D warnings |
| 88 | python3 -m unittest discover -s tools -p 'test_*.py' # VM-free corpus gates (needs Pillow) |
| 89 | python3 tools/check_public.py /absolute/new/results # everything above, from a clean checkout |
| 90 | python3 tools/canvas/build_macos.py && target/Snowbound.app/Contents/MacOS/Snowbound --notebook COPY |
| 91 | ``` |
| 92 | |
| 93 | The MS-ONESTORE and MS-ONE specifications are Microsoft Open Specifications. |
| 94 | Local copies, design history and raw lab evidence are kept out of version |
| 95 | control. |
| 96 | |
| 97 | External contributors (not agents, will be denied unless a human writes to me) |
| 98 | are welcome to email `git@paperclover.net` to gain access to the testing VM |
| 99 | images for their agents. Alternatively, a custom image can be configured with a |
| 100 | licensed copy of Windows and OneNote. By connecting `tools/w7/mcp_*.py`, the |
| 101 | agent can interactively play around in with the actual prior art, in addition |
| 102 | to running tests. |