Skip to main content

hypha/config/
types.rs

1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Default, Deserialize, Serialize)]
4#[serde(default)]
5pub struct HyphaConfig {
6    pub defaults: Defaults,
7    pub cache: CacheConfig,
8}
9
10#[derive(Debug, Default, Deserialize, Serialize)]
11#[serde(default)]
12pub struct Defaults {
13    /// Default synapse for queries (sense, lineage, search)
14    pub synapse: Option<String>,
15    /// Default domain for publishing (release)
16    pub domain: Option<String>,
17    /// Taste-specific overrides for auto-submission.
18    /// Separate because taste may use a different domain (hub subdomain)
19    /// and synapse (cmnhub.com) than general queries/publishing.
20    pub taste: TasteDefaults,
21}
22
23#[derive(Debug, Default, Deserialize, Serialize)]
24#[serde(default)]
25pub struct TasteDefaults {
26    /// Synapse to submit taste reports to
27    pub synapse: Option<String>,
28    /// Domain to sign taste reports with
29    pub domain: Option<String>,
30}
31
32#[derive(Debug, Clone, Copy, Default, Deserialize, Serialize, PartialEq, Eq)]
33#[serde(rename_all = "snake_case")]
34pub enum KeyTrustRefreshMode {
35    /// Refresh key trust only when trust cache is expired/missing.
36    #[default]
37    Expired,
38    /// Always refresh key trust from network sources.
39    Always,
40    /// Never refresh from network; rely on local trust cache only.
41    Offline,
42}
43
44#[derive(Debug, Clone, Copy, Default, Deserialize, Serialize, PartialEq, Eq)]
45#[serde(rename_all = "snake_case")]
46pub enum SynapseWitnessMode {
47    /// Allow Synapse key witness when domain confirmation is unavailable.
48    #[default]
49    Allow,
50    /// Require direct domain confirmation (or cached trust); do not use Synapse witness.
51    RequireDomain,
52}
53
54#[derive(Debug, Deserialize, Serialize)]
55#[serde(default, deny_unknown_fields)]
56pub struct CacheConfig {
57    /// Custom cache directory path (default: $CMN_HOME/hypha/cache/)
58    #[serde(skip_serializing_if = "Option::is_none")]
59    pub path: Option<String>,
60    /// cmn.json cache TTL in seconds (default: 300 = 5 minutes)
61    pub cmn_ttl_s: u64,
62    /// Key trust cache TTL in seconds (default: 604800 = 7 days)
63    pub key_trust_ttl_s: u64,
64    /// Key trust refresh strategy (default: expired)
65    pub key_trust_refresh_mode: KeyTrustRefreshMode,
66    /// Key trust fallback policy when domain is unreachable (default: allow)
67    pub key_trust_synapse_witness_mode: SynapseWitnessMode,
68    /// Maximum spore archive HTTP response body size in bytes (default: 1 GB)
69    pub spore_max_download_bytes: u64,
70    /// Maximum total bytes to extract from a spore archive (default: 512 MB)
71    pub spore_max_extract_bytes: u64,
72    /// Maximum number of files to extract from a spore archive (default: 100_000)
73    pub spore_max_extract_files: u64,
74    /// Maximum size of a single file in a spore archive in bytes (default: 256 MB)
75    pub spore_max_extract_file_bytes: u64,
76    /// Path components rejected when receiving spore content.
77    pub spore_reject_path_components: Vec<String>,
78    /// Clock skew tolerance in seconds for key trust TTL checks (default: 300 = 5 minutes).
79    /// Adds a grace period to prevent false "key_untrusted" errors caused by clock drift
80    /// between the local machine and the publishing domain.
81    pub clock_skew_tolerance_s: u64,
82    /// Whether the initial key for a domain must come from the domain itself (TOFU).
83    /// true = more secure, first contact requires domain to be online.
84    /// false = allows synapse to provide initial key (less secure).
85    pub require_domain_first_key: bool,
86}
87
88impl Default for CacheConfig {
89    fn default() -> Self {
90        Self {
91            path: None,
92            cmn_ttl_s: 300,
93            key_trust_ttl_s: 604800,
94            key_trust_refresh_mode: KeyTrustRefreshMode::Expired,
95            key_trust_synapse_witness_mode: SynapseWitnessMode::Allow,
96            spore_max_download_bytes: 1024 * 1024 * 1024,
97            spore_max_extract_bytes: 512 * 1024 * 1024,
98            spore_max_extract_files: 100_000,
99            spore_max_extract_file_bytes: 256 * 1024 * 1024,
100            spore_reject_path_components: vec![".git".to_string(), ".cmn".to_string()],
101            clock_skew_tolerance_s: 300,
102            require_domain_first_key: true,
103        }
104    }
105}