use thiserror::Error;
#[derive(Debug, Error, PartialEq, Eq)]
#[non_exhaustive]
pub enum KyaError {
#[error("delegation chain is empty")]
EmptyChain,
#[error("storage backend failure: {0}")]
StorageFailure(String),
#[error("chain does not anchor to the declared principal")]
RootMismatch,
#[error("delegation linkage broken at hop {0}")]
BrokenLinkage(usize),
#[error("invalid signature at hop {0}")]
InvalidSignature(usize),
#[error("delegation at hop {0} not yet valid (issued_at={1}, now={2})")]
NotYetValid(usize, u64, u64),
#[error("delegation at hop {0} has expired (expiry={1}, now={2})")]
Expired(usize, u64, u64),
#[error("temporal violation at hop {0}: child expiry {1} exceeds parent expiry {2}")]
TemporalViolation(usize, u64, u64),
#[error("depth limit exceeded at hop {0} (limit={1})")]
MaxDepthExceeded(usize, u8),
#[error("sub-scope proof is structurally invalid")]
InvalidSubScopeProof,
#[error("scope escalation at hop {0}: delegated scope is not within the delegator's authorization")]
ScopeEscalation(usize),
#[error("executing agent is not the terminal delegate")]
UnauthorizedLeaf,
#[error("execution intent is not within the terminal scope")]
ScopeViolation,
#[error("nonce has already been consumed")]
NonceReplay,
#[error("delegation certificate has been revoked")]
Revoked,
#[error("intent is not present in this tree")]
IntentNotFound,
#[error("intent tree requires at least one intent")]
EmptyTree,
}