Files
varde/docs/milestone-1.md
T
bl 4e1a95613b Milestone 1: workspace skeleton, wire protocol, socket round-trip
Three-crate workspace per SPECS.md. varde-proto defines the full JSON
Lines protocol (requests, envelopes, structured errors, events) with
string-typed hashes so the crate carries no iroh dependency. The daemon
binds its unix socket, loads config with flags > env > file > defaults
precedence, and answers status/list; everything else returns a
structured "unimplemented" error. varde-ctl maps subcommands 1:1 onto
requests and round-trips status against a real daemon in the tests.

Dependencies: serde/serde_json (wire format), tokio (async runtime and
unix sockets), tracing/tracing-subscriber (structured logging), toml
(config file), anyhow (binary-edge errors), thiserror (reserved for
library errors), clap (ctl flag parsing, per spec), tempfile (dev-only,
ephemeral test dirs).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 20:10:29 +02:00

48 lines
2.6 KiB
Markdown

# Milestone 1 — Skeleton
Workspace with the three crates from the spec, the full wire protocol, a
daemon that binds its socket and answers, and a `varde-ctl` that
round-trips `status` against it.
## Decisions
- **Wire types use strings for hashes/tickets/node ids.** `varde-proto`
stays free of iroh dependencies ("No I/O" taken to also mean no heavy
type imports), and the protocol is consumable from any language without
linking iroh. The daemon parses/validates at its boundary.
- **Envelope shape.** Every reply is `{"ok": bool, "data": {...}}` or
`{"ok": false, "error": {"code", "message"}}`. `data` is internally
tagged with `kind` so clients can dispatch without guessing. Error codes
are a closed enum (`bad_request`, `invalid_argument`, `not_found`, `io`,
`internal`, `unimplemented`).
- **The full request surface is defined now**, including peer-trust and
ticket ops. Unimplemented handlers return a structured `unimplemented`
error instead of the protocol growing per milestone.
- **`varde-daemon` is a lib + thin bin.** Integration tests run real
daemons: the daemon crate's tests spawn the actual binary
(`CARGO_BIN_EXE_varde-daemon`) on ephemeral sockets; the ctl crate's
test runs an in-process daemon (same `run()` entry point) and drives the
real `varde-ctl` binary against it. No mocked transport anywhere.
- **Daemon flag parsing is hand-rolled** (five flags); the spec reserves
clap for `varde-ctl`. Mode (system/user) defaults from euid — root gets
`/var/lib/varde` + `/run/varde/varde.sock`, users get XDG paths — and
`geteuid` is called through a two-line FFI shim instead of pulling in
the `libc` crate for one function.
- **Config precedence** is flags > `VARDE_*` env > TOML file > defaults,
implemented per-field so partial configs compose. An absent or empty
default config file is valid; an explicitly named one must exist.
Unknown keys in the file are rejected (`deny_unknown_fields`) so typos
fail loudly at startup rather than silently using defaults.
- **Defaults encode the traffic posture**: `wan_upload = false`,
upload cap 10 MB/s, discovery on (discovery is the open tier; serving
is still gated on trust, which doesn't exist until milestone 4).
- **Event plumbing exists from day one.** `Subscribe` flips a connection
into a one-way stream fed by a bounded `tokio::broadcast` channel
(laggards drop events rather than buffering unboundedly). Milestones 3/4
publish into it.
## Deviations from the spec
None of substance. `--json` output for `varde-ctl` (a milestone 5 item)
landed early because the printing layer needed a shape anyway.