# 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.