Skip to main content

shep_core/protocol/
mod.rs

1//! The client<->daemon wire protocol (version 3)
2//!
3//! Typed request/response enums + bus events. Framing lives in [`wire`];
4//! every type here is snapshot-pinned — changing any serialized shape is a
5//! protocol version bump recorded in the CHANGELOG.
6//!
7//! **What version 2 added:** the instance slot on [`ProcessInfo`]. A sheep
8//! that is one of several instances of an app reports which slot it is, so
9//! every listing can group an app's instances and roll their numbers up
10//! rather than showing several rows that share a name and explain nothing.
11//! A sheep reports its own slot, counting from 0, so a single-instance app
12//! reports `Some(0)`. `None` means the peer daemon predates the field, and a
13//! reader that finds it should render exactly what it rendered before this
14//! field existed.
15//!
16//! **What version 3 changed:** `ResetDepth::Settings` was renamed to
17//! `ResetDepth::Policy` (and gained `File`/`Env` siblings). Unlike every
18//! bump before it except `SelectorSpec::Instance`'s, this one is not an
19//! addition: `"settings"` was the wire spelling of a `Request::ApplyConfig`
20//! already shipping, and a rename removes a string an older daemon already
21//! decoded rather than adding one it never saw. Without the bump, a CLI
22//! built after this change sends `"policy"` for what used to be `--reset`,
23//! and a daemon that has not restarted since the upgrade cannot decode it:
24//! the connection ends on an envelope it cannot read instead of a named
25//! refusal at the handshake. Restart the shepherd after upgrading to this
26//! version, the same as the last bump asked.
27//!
28//! **Two sets of tests carry a version in their name and they assert
29//! opposite things.** The `*_wire_v3` snapshots pin the shape this crate
30//! serializes TODAY, so they follow [`PROTOCOL_VERSION`] and get renamed
31//! whenever it moves. The `v1_*_fixture_still_deserializes` tests pin a
32//! literal payload captured from a version 1 peer and assert it STILL
33//! decodes, so their name records where the bytes came from and never
34//! moves; renaming one would erase the compatibility claim it exists to
35//! make.
36
37pub mod channel;
38pub mod events;
39pub mod frame;
40pub mod request;
41/// Frame encoding shared by daemon and client
42pub mod wire;
43
44pub use channel::{CHANNEL_VERSION, ChildMessage, ShepherdMessage};
45pub use events::{BusEvent, ProcessEventKind};
46pub use frame::ServerFrame;
47pub use request::{
48    ActionOutcome, ActionReply, DogSectionToml, DogSource, Envelope, ExitInfo, Hello, HelloAck,
49    HelloReply, Lamb, LineOutcome, LineReply, ProcessInfo, ProcessInfoBuilder, Reply, Request,
50    Response, RpcError, RpcErrorCode, SelectorSpec, SheepApplied, SheepDrift, SignalOutcome,
51    SignalReply, Smit, SmitError, sort_flock,
52};
53pub use wire::{MAX_FRAME_BYTES, WireError, codec, decode_frame, encode_frame};
54
55/// Wire protocol version.
56///
57/// Evolution rule: ADDITIVE optional fields (new serde-defaulted `Option<T>`
58/// fields, new variants behind `#[non_exhaustive]`) keep the version.
59/// Removing, renaming, or retyping anything serialized bumps it, recorded in
60/// the CHANGELOG. Byte fixtures in each protocol module pin the deserialize
61/// direction.
62pub const PROTOCOL_VERSION: u32 = 3;