Expand description
kindling-runtime — the anvil-first integration facade.
One Cargo dependency that bundles daemon startup, client wiring, and durable
emit for Rust downstreams (chiefly anvil) that want one binary and
daemon semantics without a separate kindling install.
The runtime composes the existing crates — it does not fork their wire shapes:
kindling-clientfor the HTTP-over-UDS surface (re-exported asClient).- the opt-in
spoollayer for durable emit (re-exported asSpooledClient). kindling-serverstarted in-process on a tokio task (theembedded-daemonfeature).kindling-typesre-exported astypes(and the common shapes at the crate root) so consumers need no separate dep.
kindling stays mechanism, not policy: the runtime owns process lifecycle and client wiring; it does not encode anvil governance.
§Quickstart
use kindling_runtime::{Runtime, RuntimeConfig};
use kindling_runtime::types::{ObservationInput, ObservationKind, ScopeIds};
// Embedded daemon (default), durable spooled emit, default ~/.kindling home.
let runtime = Runtime::start(RuntimeConfig::embedded("/path/to/my/project")).await?;
// Durable append: reaches the daemon, or buffers to the spool on outage.
let input = ObservationInput {
id: None,
kind: ObservationKind::Message,
content: "gate evaluated: pass".to_string(),
provenance: None,
ts: None,
scope_ids: ScopeIds::default(),
redacted: None,
};
runtime
.spooled_client()
.append_observation(input, None, None)
.await
.expect("durable append");
runtime.shutdown().await?;§Attach-or-start
Runtime::start never pre-emptively starts a daemon. It builds a client
for the configured socket; the client only spawns when the socket does not
answer. So if a daemon (the CLI, a Claude Code hook, or another runtime) is
already listening on the same socket, the runtime attaches to it and the
embedded spawner is not invoked.
This “attach, don’t spawn” guarantee holds for the sequential case: a
daemon that is already bound when start runs is attached
to. It is not a cross-process lock. If two cold-starts race on the same
socket (neither daemon bound yet), both embedded spawners can briefly fire;
the second serve then fails to bind the already-taken socket and its task
exits cleanly, leaving exactly one daemon. For v1 anvil (a single binary
owning its socket) this window does not arise, so the runtime deliberately
ships no socket lock — see the design spec’s “socket lock file” note.
Re-exports§
pub use kindling_types as types;
Structs§
- Capsule
- Bounded unit of meaning grouping related observations.
- Client
- A thin async client for the kindling daemon.
- Client
Config - Configuration for a
Client. - Flush
Report - Result of
SpooledClient::flush. - Observation
- Atomic, immutable record of an event captured during development.
- Observation
Input - Input for creating a new observation. Optional fields are auto-generated.
- Pin
- Pinned reference to an observation or summary.
- Retrieve
Options - Options for a retrieval request.
- Retrieve
Result - Complete retrieval result: pins, optional current summary, ranked candidates, provenance.
- Runtime
- A composed kindling integration: a client (and durable-emit spooled client) over a daemon the runtime either started in-process or attached to.
- Runtime
Config - Configuration for a
Runtime. - Scope
Ids - Scope identifiers for multi-dimensional isolation.
- Spooled
Client - A durable-emit wrapper around a
crate::Client.
Enums§
- Append
Outcome - Outcome of
SpooledClient::append_observation. - Capsule
Status - Capsule lifecycle status.
- Capsule
Type - Types of capsules.
- Client
Error - Errors returned by
Clientoperations. - Observation
Kind - Types of observations that can be captured.
- Runtime
Error - Errors from
Runtimeoperations. - Spawn
Strategy - How the runtime obtains a running daemon when the socket is not answering.
- Spawner
- How the client starts the daemon when it is not already running.
- Spool
Error - Errors from
SpooledClientoperations. - Transport
- Which transport the client uses to reach the daemon.
Type Aliases§
- Id
- Unique identifier for entities. Implementation uses UUIDv4 format.