Skip to main content

liminal_server/agents/
error.rs

1//! Named failures that never retain request words or credentials.
2
3/// Why an agent operation did nothing, or why its durable outcome is unknown.
4#[derive(Debug, thiserror::Error)]
5pub enum AgentError {
6    /// A deliberate act is still a draft in Lys.
7    #[error("{action} is deliberate: held by draft {draft}")]
8    Held {
9        /// The requested action.
10        action: String,
11        /// The retained draft id.
12        draft: String,
13    },
14    /// A boundary value is malformed; only the member is named.
15    #[error("agent_invalid: {0}")]
16    Invalid(&'static str),
17    /// A name has no retained record.
18    #[error("unknown_agent: {0}")]
19    Unknown(String),
20    /// A retained name cannot be reused, including after retirement.
21    #[error("agent_name_taken: {0}")]
22    NameTaken(String),
23    /// An identity claim does not match the verified pass.
24    #[error("pass holder {holder} is not agent {agent}")]
25    Identity {
26        /// The verified holder, or unverified.
27        holder: String,
28        /// The claimed agent.
29        agent: String,
30    },
31    /// Another live connection holds this agent's seat. It is never taken
32    /// over or shared: the seat is released when that connection closes, or
33    /// when its peer stops answering the kernel's keepalive.
34    #[error(
35        "agent {agent} is already present on connection {connection}, held since unix ms \
36         {since_ms}; the seat frees when that connection closes or its peer stops answering \
37         keepalive (80 s), so give this client a seat of its own"
38    )]
39    Present {
40        /// The agent's name.
41        agent: String,
42        /// The incumbent connection.
43        connection: u64,
44        /// Epoch milliseconds the incumbent was admitted.
45        since_ms: u64,
46    },
47    /// A configured count or byte bound is reached.
48    #[error("auth.lys.agents.{bound}: limit {limit}, count {count}")]
49    Bound {
50        /// The configuration member.
51        bound: &'static str,
52        /// The configured limit.
53        limit: usize,
54        /// The measured population or byte count.
55        count: usize,
56    },
57    /// The state machine does not admit this event.
58    #[error("agent_transition_refused: {0}")]
59    Transition(&'static str),
60    /// A draft id is already bound to different immutable words.
61    #[error("agent_draft_digest_mismatch")]
62    DraftMismatch,
63    /// Only the server writes presence and state.
64    #[error("agent_subject_server_owned: {0}")]
65    ServerOwned(String),
66    /// A lock or store failed; request bodies are never included.
67    #[error("agent_registry_unavailable: {0}")]
68    Store(String),
69    /// A write may have committed; reopen before making another decision.
70    #[error("agent_registry_outcome_unknown: reopen the store before admission")]
71    Uncertain,
72    /// The library refused delivery, with no body retained in the error.
73    #[error("agent_delivery_failed: {0}")]
74    Delivery(&'static str),
75}