- The dev build tag reads web/dist from disk instead of embedding it,
so the backend starts without building the frontend first; Vite
serves the UI and proxies /api and WebSocket to the Go server
- Document the two-terminal dev workflow and ignore .dev-data/
- vault: path validation (no traversal, hidden segments or symlink
escape), atomic writes with If-Match/If-None-Match revisions, moves
that carry the note's .assets folder and rewrite its image links,
trash with restore, content-addressed asset uploads
- auth: single-user Argon2id password, sliding sessions in SQLite,
login rate limiting, first-run setup gated by a one-time code written
to the data directory
- watch: fsnotify plus periodic rescans diffed against a snapshot, so
both RawMark and external edits are broadcast as tree/changed/moved/
deleted events over WebSocket
- api: stdlib router, SameSite=Strict cookies plus Origin checks,
sandboxed raw file serving, embedded SPA with gzip and CSP