pub trait Capability: Send + Sync {
// Required methods
fn name(&self) -> &'static str;
fn description(&self) -> &'static str;
fn schema(&self) -> Value;
fn validate(&self, args: &Value) -> Result<()>;
fn execute(&self, args: &Value, ctx: &Context) -> Result<Output>;
}Expand description
The Capability trait — all capabilities must implement this.
Each capability defines its name, argument schema, validation logic,
and execution behavior. The executor calls these methods in order:
name() → schema() → validate() → execute().
§Example
use runtimo_core::capability::{Capability, Context, Output};
use runtimo_core::Result;
use serde_json::Value;
struct Echo;
impl Capability for Echo {
fn name(&self) -> &'static str { "Echo" }
fn description(&self) -> &'static str { "Echo back arguments" }
fn schema(&self) -> Value { serde_json::json!({"type":"object"}) }
fn validate(&self, _args: &Value) -> Result<()> { Ok(()) }
fn execute(&self, args: &Value, _ctx: &Context) -> Result<Output> {
Ok(Output::ok(format!("echo: {}", args)))
}
}Required Methods§
Sourcefn name(&self) -> &'static str
fn name(&self) -> &'static str
Returns the capability name (e.g., "FileRead", "FileWrite").
This name is used for registry lookups and WAL event tagging.
Sourcefn description(&self) -> &'static str
fn description(&self) -> &'static str
Returns a one-line human-readable description of what this capability does.
Used by the CLI list command and --help output to help users
discover available capabilities.
Sourcefn schema(&self) -> Value
fn schema(&self) -> Value
Returns the JSON Schema for the capability’s arguments.
The schema is used by Capability::validate and by the CLI
to generate --help output for each capability.
Sourcefn validate(&self, args: &Value) -> Result<()>
fn validate(&self, args: &Value) -> Result<()>
Validates the arguments against the schema.
Implementations should deserialize args into their typed args struct
and perform semantic checks (e.g., path traversal rejection).
§Errors
Returns Error::SchemaValidationFailed
if arguments are malformed or semantically invalid.
Sourcefn execute(&self, args: &Value, ctx: &Context) -> Result<Output>
fn execute(&self, args: &Value, ctx: &Context) -> Result<Output>
Executes the capability with the given arguments and context.
This is called after validate() passes. Implementations should
perform the actual work and return an Output.
§Errors
Returns Error::ExecutionFailed
if the operation cannot be completed.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".
Implementors§
impl<T: TypedCapability> Capability for T
Blanket implementation bridging TypedCapability to Capability.
This is the critical bridge that allows the executor’s &dyn Capability
dynamic dispatch to work with typed capabilities. When the executor calls
Capability::execute(&dyn Capability, &Value, &Context), this impl:
- Deserializes the
ValueintoT::Args(one deserialization). - Calls
TypedCapability::executewith the typed args. - Maps
CapabilityErrortocrate::Error.
The validate method always returns Ok(()) because deserialization
is validation — serde_json::from_value rejects malformed input.
§Why this exists
Without this blanket impl, TypedCapability would be unusable by the
executor (which stores Box<dyn Capability>). With it, both paths
coexist:
- Dynamic dispatch (executor):
cap.execute(&value, &ctx)— goes through this blanket impl. - Static dispatch (direct callers):
cap.execute(typed_args, &ctx)— callsTypedCapability::executedirectly.