1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
//! Input contracts compiled into the stable-only MCP artifact.
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize, JsonSchema)]
pub enum EdgeType {
/// Semantic similarity edge (requires cosine_similarity)
Semantic,
/// Temporal ordering edge (requires delta_secs)
Temporal,
/// Causal relationship edge (requires confidence)
Causal,
/// Named relationship edge (requires relation)
Entity,
}
#[derive(Debug, Deserialize, JsonSchema)]
pub struct SearchParams {
/// The search query string
pub query: String,
/// Maximum number of results to return (default 5)
#[serde(default)]
pub top_k: Option<u32>,
/// Optional namespace filter (restrict search to these namespaces)
#[serde(default)]
pub namespaces: Option<Vec<String>>,
}
#[derive(Debug, Deserialize, JsonSchema)]
pub struct SearchWitnessedParams {
pub query: String,
#[serde(default)]
pub top_k: Option<u32>,
#[serde(default)]
pub namespaces: Option<Vec<String>>,
/// Optional caller correlation ID; generated when omitted.
#[serde(default)]
pub request_id: Option<String>,
/// Retrieval stage selection. Defaults to the current hybrid behavior.
#[serde(default)]
pub retrieval_mode: Option<RetrievalModeParam>,
/// Replay input retention. Defaults to no_replay for privacy.
#[serde(default)]
pub replay_mode: Option<ReplayModeParam>,
}
#[derive(Debug, Clone, Copy, Deserialize, Serialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum RetrievalModeParam {
Hybrid,
FtsOnly,
VectorOnly,
}
#[derive(Debug, Clone, Copy, Deserialize, Serialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum ReplayModeParam {
NoReplay,
StoreInputs,
}
#[derive(Debug, Clone, Deserialize, JsonSchema)]
pub struct GovernedNamespaceScopeParams {
pub namespace: String,
#[serde(default)]
pub domain: Option<String>,
#[serde(default)]
pub workspace_id: Option<String>,
#[serde(default)]
pub repo_id: Option<String>,
}
#[derive(Debug, Clone, Copy, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum GovernedAccessPurposeParam {
Recall,
Assertion,
Action,
Export,
Replay,
Admin,
}
#[derive(Debug, Clone, Deserialize, JsonSchema)]
pub struct GovernedLeaseParams {
pub lease_id: String,
pub delegator: String,
pub delegatee: String,
pub purposes: Vec<GovernedAccessPurposeParam>,
pub scope: GovernedNamespaceScopeParams,
#[serde(default)]
pub audiences: Vec<String>,
pub expires_at: String,
#[serde(default)]
pub revoked: bool,
#[serde(default)]
pub elevation: bool,
}
#[derive(Debug, Clone, Deserialize, JsonSchema)]
pub struct GovernedDecisionParams {
pub fact_id: String,
pub caller: String,
pub subject: String,
pub audiences: Vec<String>,
pub scope: GovernedNamespaceScopeParams,
#[serde(default)]
pub delegation_or_elevation: Option<GovernedLeaseParams>,
}
#[derive(Debug, Deserialize, JsonSchema)]
pub struct AddFactParams {
/// The fact content text
pub content: String,
/// Namespace to store the fact in (e.g. "general", "research", "coding")
pub namespace: String,
/// Optional source attribution
#[serde(default)]
pub source: Option<String>,
/// When true, extract named entities via Ollama and link them as graph edges (opt-in)
#[serde(default)]
pub extract_entities: Option<bool>,
/// Memory kind classification: durable_fact, preference, project_state, instruction_policy,
/// correction, observation, episode_summary, skill_procedure, ephemeral_inference.
/// Default: durable_fact. Ephemeral inferences require evidence_refs to promote.
#[serde(default)]
pub memory_kind: Option<String>,
/// Sensitivity class: public, internal, confidential, restricted.
/// Default: internal. Confidential/restricted facts are blocked from autocapture.
#[serde(default)]
pub sensitivity: Option<String>,
/// Evidence references supporting this fact (URLs, fact IDs, source paths).
#[serde(default)]
pub evidence_refs: Option<Vec<String>>,
/// Optional caller-provided idempotency key. Retries with the same key and
/// payload return the original fact; omit it for a distinct append.
#[serde(default)]
pub idempotency_key: Option<String>,
}
#[derive(Debug, Deserialize, JsonSchema)]
pub struct GraphPathParams {
/// Starting item ID
pub from_id: String,
/// Target item ID
pub to_id: String,
/// Maximum BFS depth (default 5)
#[serde(default)]
pub max_depth: Option<u32>,
}
#[derive(Debug, Deserialize, JsonSchema)]
pub struct AddGraphEdgeParams {
/// Source node ID (prefixed, e.g. "fact:<uuid>", "namespace:<name>")
pub source: String,
/// Target node ID (prefixed)
pub target: String,
/// Edge type: semantic, temporal, causal, or entity
pub edge_type: EdgeType,
/// Edge weight (default 1.0)
#[serde(default = "default_weight")]
pub weight: f64,
/// For semantic edges: cosine similarity (0.0-1.0). Ignored for other types.
#[serde(default)]
pub cosine_similarity: Option<f32>,
/// For temporal edges: time delta in seconds. Ignored for other types.
#[serde(default)]
pub delta_secs: Option<u64>,
/// For causal edges: confidence (0.0-1.0). Ignored for other types.
#[serde(default)]
pub confidence: Option<f32>,
/// For causal edges: evidence IDs. Ignored for other types.
#[serde(default)]
pub evidence_ids: Option<Vec<String>>,
/// For entity edges: relationship name (e.g. "mentions", "modifies"). Ignored for other types.
#[serde(default)]
pub relation: Option<String>,
/// Optional metadata as a JSON object string
#[serde(default)]
pub metadata: Option<String>,
}
fn default_weight() -> f64 {
1.0
}
#[derive(Debug, Deserialize, JsonSchema)]
pub struct GetFactParams {
/// The fact id. Accepts a bare UUID or a prefixed id like "fact:<uuid>".
pub fact_id: String,
}
#[derive(Debug, Deserialize, JsonSchema)]
pub struct GetFactNeighborsParams {
/// The node id whose neighbors to fetch (bare UUID or prefixed "fact:<uuid>").
pub item_id: String,
}
#[derive(Debug, Deserialize, JsonSchema)]
pub struct SupersedeFactParams {
/// Existing stale fact id. Accepts a bare UUID or prefixed "fact:<uuid>".
pub old_fact_id: String,
/// Replacement fact content.
pub content: String,
/// Optional namespace for the replacement fact. Defaults to the old fact's namespace.
#[serde(default)]
pub namespace: Option<String>,
/// Optional source attribution for the replacement fact.
#[serde(default)]
pub source: Option<String>,
/// Optional reason stored on the supersedes graph edge.
#[serde(default)]
pub reason: Option<String>,
}
#[derive(Debug, Deserialize, JsonSchema)]
pub struct SearchConversationsParams {
/// The search query string.
pub query: String,
/// Maximum number of results (default 5).
#[serde(default)]
pub top_k: Option<u32>,
}