khive_vcs/error.rs
1// Copyright 2026 khive contributors. Licensed under Apache-2.0.
2//
3//! Error types for the VCS layer.
4//!
5//! Remote-server and custom-push/pull error variants (`RemoteUnreachable`,
6//! `AuthFailed`, `NonFastForward`, `MergeRequired`) were removed per ADR-010/
7//! ADR-020: git is the remote protocol; there is no custom `khive-sync` server.
8//! `MergeNotImplemented` was removed because the custom merge engine is
9//! superseded for v1 (ADR-020 §what-adr-010-retains-this-adr-replaces).
10
11use thiserror::Error;
12
13use crate::types::SnapshotId;
14
15#[derive(Debug, Error)]
16pub enum VcsError {
17 /// The archive stored at the remote has a different hash than expected.
18 /// Indicates corruption or tampering.
19 #[error("hash mismatch: expected {expected}, actual {actual}")]
20 HashMismatch {
21 expected: SnapshotId,
22 actual: SnapshotId,
23 },
24
25 /// `checkout` was blocked because there are uncommitted changes.
26 /// Pass `force: true` to discard them.
27 #[error("uncommitted changes: {count} entities/edges modified since last commit")]
28 UncommittedChanges { count: usize },
29
30 /// A `SnapshotId` string failed validation.
31 #[error("invalid snapshot id: {0}")]
32 InvalidSnapshotId(String),
33
34 /// A branch name failed validation (must match `^[a-zA-Z0-9_-]{1,64}$`).
35 #[error("invalid branch name: {0:?}")]
36 InvalidBranchName(String),
37
38 /// An underlying storage operation failed.
39 #[error("storage: {0}")]
40 Storage(String),
41
42 /// JSON serialization or deserialization failed.
43 #[error("json: {0}")]
44 Json(#[from] serde_json::Error),
45
46 /// An I/O operation failed (file system).
47 #[error("io: {0}")]
48 Io(#[from] std::io::Error),
49
50 /// An unexpected internal error.
51 #[error("internal: {0}")]
52 Internal(String),
53}
54
55impl From<khive_runtime::error::RuntimeError> for VcsError {
56 fn from(e: khive_runtime::error::RuntimeError) -> Self {
57 VcsError::Storage(e.to_string())
58 }
59}