#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TierHint {
Read,
Write,
Execute,
Destructive,
External,
}
impl TierHint {
pub fn as_str(&self) -> &'static str {
match self {
Self::Read => "read",
Self::Write => "write",
Self::Execute => "execute",
Self::Destructive => "destructive",
Self::External => "external",
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct VerbSpec {
pub ns: &'static str,
pub action: &'static str,
pub tier_hint: TierHint,
pub summary: &'static str,
}
impl VerbSpec {
pub fn dotted(&self) -> String {
format!("{}.{}", self.ns, self.action)
}
}
pub const VERBS: &[VerbSpec] = &[
VerbSpec {
ns: "memory",
action: "store",
tier_hint: TierHint::Write,
summary: "Store a subject-predicate-object fact in semantic memory.",
},
VerbSpec {
ns: "memory",
action: "delete",
tier_hint: TierHint::Destructive,
summary: "Delete matching semantic facts (irreversible).",
},
VerbSpec {
ns: "memory",
action: "import",
tier_hint: TierHint::Write,
summary: "Bulk-import memory entries from a filesystem path.",
},
VerbSpec {
ns: "memory",
action: "export",
tier_hint: TierHint::Write,
summary: "Bulk-export memory entries to a filesystem path.",
},
VerbSpec {
ns: "shell",
action: "exec",
tier_hint: TierHint::Execute,
summary: "Run a one-shot sandboxed command via the action dispatcher.",
},
VerbSpec {
ns: "terminal",
action: "open",
tier_hint: TierHint::Execute,
summary: "Open a persistent PTY session through the terminal bridge.",
},
VerbSpec {
ns: "terminal",
action: "close",
tier_hint: TierHint::Write,
summary: "Close a previously-opened PTY session.",
},
VerbSpec {
ns: "net",
action: "http",
tier_hint: TierHint::External,
summary: "Perform an outbound HTTP request (web search, fetch).",
},
VerbSpec {
ns: "net",
action: "check",
tier_hint: TierHint::External,
summary: "Check reachability of a host: DNS resolution + timed TCP connect.",
},
VerbSpec {
ns: "net",
action: "trace",
tier_hint: TierHint::External,
summary: "Trace the network route (hops) to a host.",
},
VerbSpec {
ns: "net",
action: "cert",
tier_hint: TierHint::External,
summary: "Inspect the TLS certificate chain a host presents (validity, SANs).",
},
VerbSpec {
ns: "notify",
action: "send",
tier_hint: TierHint::External,
summary: "Send a message through the channel dispatcher.",
},
VerbSpec {
ns: "schedule",
action: "create",
tier_hint: TierHint::External,
summary: "Persist a scheduled-intent row.",
},
VerbSpec {
ns: "schedule",
action: "cancel",
tier_hint: TierHint::Write,
summary: "Cancel a scheduled-intent row.",
},
VerbSpec {
ns: "task",
action: "decompose",
tier_hint: TierHint::Execute,
summary: "Decompose a request into an orchestrator task plan.",
},
VerbSpec {
ns: "task",
action: "cancel",
tier_hint: TierHint::Write,
summary: "Abort a running orchestrator task.",
},
VerbSpec {
ns: "signal",
action: "cancel",
tier_hint: TierHint::Write,
summary: "Cancel an in-flight signal pipeline run.",
},
VerbSpec {
ns: "agent",
action: "delegate",
tier_hint: TierHint::Execute,
summary: "Hand a subtask to a discovered subprocess agent.",
},
VerbSpec {
ns: "approval",
action: "respond",
tier_hint: TierHint::Write,
summary: "Approve or reject a pending confirmation by nonce.",
},
VerbSpec {
ns: "approval",
action: "revoke",
tier_hint: TierHint::Write,
summary: "Revoke a standing approval grant.",
},
VerbSpec {
ns: "audit",
action: "prune",
tier_hint: TierHint::Destructive,
summary: "Prune audit-log rows older than the given duration.",
},
VerbSpec {
ns: "security",
action: "audit",
tier_hint: TierHint::Read,
summary: "Audit the security posture of the current configuration.",
},
VerbSpec {
ns: "logs",
action: "analyze",
tier_hint: TierHint::Read,
summary: "Analyse recent logs for recurring error/warning patterns.",
},
VerbSpec {
ns: "baseline",
action: "capture",
tier_hint: TierHint::Write,
summary: "Capture a system-baseline snapshot for later drift detection.",
},
VerbSpec {
ns: "baseline",
action: "diff",
tier_hint: TierHint::Read,
summary: "Diff a baseline against another snapshot or the live state.",
},
VerbSpec {
ns: "baseline",
action: "list",
tier_hint: TierHint::Read,
summary: "List stored baseline snapshots.",
},
VerbSpec {
ns: "channel",
action: "configure",
tier_hint: TierHint::Write,
summary: "Adjust a channel-preference weight or pin.",
},
VerbSpec {
ns: "proactivity",
action: "configure",
tier_hint: TierHint::Write,
summary: "Toggle or rate-limit the proactivity engine.",
},
VerbSpec {
ns: "fs",
action: "read",
tier_hint: TierHint::Read,
summary: "Read a filesystem path inside security.allowed_paths.",
},
VerbSpec {
ns: "mcp",
action: "mount",
tier_hint: TierHint::External,
summary: "Mount an external MCP server (stdio or HTTP transport).",
},
VerbSpec {
ns: "mcp",
action: "unmount",
tier_hint: TierHint::Write,
summary: "Unmount a previously-mounted MCP server.",
},
];
pub fn lookup(ns: &str, action: &str) -> Option<&'static VerbSpec> {
VERBS.iter().find(|v| v.ns == ns && v.action == action)
}
pub fn namespaces() -> Vec<&'static str> {
let mut out: Vec<&'static str> = VERBS.iter().map(|v| v.ns).collect();
out.sort_unstable();
out.dedup();
out
}
#[cfg(test)]
mod tests {
use super::*;
use std::collections::HashSet;
#[test]
fn verb_pairs_are_unique() {
let mut seen: HashSet<(&str, &str)> = HashSet::new();
for v in VERBS {
assert!(
seen.insert((v.ns, v.action)),
"duplicate verb pair: {}.{}",
v.ns,
v.action
);
}
}
#[test]
fn every_verb_has_a_summary() {
for v in VERBS {
assert!(
!v.summary.trim().is_empty(),
"{}.{} has empty summary",
v.ns,
v.action
);
}
}
#[test]
fn lookup_finds_known_pair() {
let v = lookup("memory", "store").expect("memory.store registered");
assert_eq!(v.tier_hint, TierHint::Write);
assert_eq!(v.dotted(), "memory.store");
}
#[test]
fn tier_hint_string_form_is_stable() {
assert_eq!(TierHint::Read.as_str(), "read");
assert_eq!(TierHint::Destructive.as_str(), "destructive");
}
#[test]
fn lookup_returns_none_for_unknown_pair() {
assert!(lookup("not", "real").is_none());
assert!(lookup("mcp", "any_tool_name").is_none());
}
#[test]
fn namespaces_are_deduped_and_sorted() {
let ns = namespaces();
let mut sorted = ns.clone();
sorted.sort_unstable();
assert_eq!(ns, sorted);
let mut deduped = ns.clone();
deduped.dedup();
assert_eq!(ns, deduped);
assert!(ns.contains(&"memory"));
assert!(ns.contains(&"mcp"));
}
#[test]
fn vocabulary_contains_expected_size() {
assert_eq!(VERBS.len(), 31);
}
}