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>
This commit is contained in:
2026-07-14 20:10:29 +02:00
commit 4e1a95613b
19 changed files with 2466 additions and 0 deletions
+23
View File
@@ -0,0 +1,23 @@
//! varde-daemon library surface.
//!
//! The daemon is a binary, but its internals are exposed as a library so
//! integration tests can run real daemons in-process on ephemeral sockets.
pub mod config;
pub mod daemon;
pub mod server;
use std::sync::Arc;
use anyhow::{Context, Result};
/// Run a daemon with the given config until the future is dropped or the
/// listener fails. Binds the socket before returning control to the
/// runtime so callers can rely on it existing once this future is polled.
pub async fn run(config: config::Config) -> Result<()> {
std::fs::create_dir_all(&config.store_dir)
.with_context(|| format!("creating store directory {}", config.store_dir.display()))?;
let listener = server::bind_socket(&config.socket_path)?;
let daemon = Arc::new(daemon::Daemon::new(config));
server::serve(listener, daemon).await
}