feat: end-to-end integrity checks with self-healing; website; installer and Windows fixes

Store::verify compares the whole SQLite projection, every table row for
row, against a fresh projection of the journal; verify_and_heal rebuilds a
drifted database (keeping the old file) at every server start and via the
new books.verify tool, which also re-hashes every blob. The GUI checks the
server's database read-only and every stored file, and shows the result.
rebuild() also drops stale WAL/SHM files.

site/: the wanderbooks website (just site, just publish). install.sh:
OS detection (Windows points to WSL2), C compiler and git checks,
WANDERBOOKS_REPO. Windows: no directory fsync off Unix; .exe-aware lookup.
Repo justfile: check, build, install, demo, site.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MtYEaR6M6Ybdhm6X98BWNu
This commit is contained in:
swaitsandClaude Opus 5.5 committed 2026-10-12 17:05:05 -07:00
1 parent 714867ed58
commit 9694d2a89a
25 files changed
+808 -41

No files matched your search

+11
View File
@@ -162,6 +162,17 @@ through the policy.
- `books.run_recurring { through? }` → `{ drafts: [{ recurring_id, date,
entry_id }] }`: one draft per occurrence on or before `through`, once.
## Tools — integrity
- `books.verify { blobs? }` → `{ status: "ok" | "healed", events, head,
healed?, blobs_verified?, checked }`. Verifies the journal's hash chain,
replays it against the live ledger, and compares every table of the
SQLite database row for row against a fresh projection of the journal.
A drifted database is rebuilt from the journal (the old file kept as
`wanderbooks.mismatch.<time>`). With `blobs` (default true), re-hashes
every stored file. The server runs the same check, and heals the same
way, every time it starts.
## Tools — payouts
- `books.record_payout { date, description, deposit_account, deposit,