4e1a95613b
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>
2.6 KiB
2.6 KiB
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-protostays 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"}}.datais internally tagged withkindso 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
unimplementederror instead of the protocol growing per milestone. varde-daemonis 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 (samerun()entry point) and drives the realvarde-ctlbinary 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 — andgeteuidis called through a two-line FFI shim instead of pulling in thelibccrate 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.
Subscribeflips a connection into a one-way stream fed by a boundedtokio::broadcastchannel (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.