# kcode-kennedy-session-tool-contracts 0.1.0
Strict, effect-free decoding and validation for Kennedy-owned Ktool arguments. This crate does not authorize or execute tools.
## Public API
```rust
pub enum DecodedTool {
RunSubagent { model: String, reasoning_effort: Option<String>, context_node_ids: Vec<String>, task: String },
EndSession { message: Option<String> },
BoxIds(Vec<kcode_session_history::chatend::BoxId>),
SummarizeBox { box_id: kcode_session_history::chatend::BoxId, summary: String },
BoxId(kcode_session_history::chatend::BoxId),
LoadNodes(Vec<String>),
EmitObject { object_id: String, file_name: Option<String> },
WebSearch { question: String, model: String },
WebFetch { url: String },
StageTelegramGroupMedia { message_id: i64 },
MediaEnrichment { object_id: String, model: String, prompt: String },
GenerateImage { model: String, prompt: String, reference_object_ids: Vec<String> },
ObjectId(String),
ConnectNodes(Vec<String>),
ConsolidateFanout { parent: String, fanout: Vec<String>, aggregator: String },
SetFixedConnection { parent: String, child: Option<String>, slot: usize },
CreateNode { parents: Vec<String>, owner: String, short_name: String, short_description: String, long_description: String },
UpdateNode { id: String, owner: String, short_name: String, short_description: String, long_description: String },
}
pub enum ValidationRequest<'a> {
Annotation { model: &'a str, media_type: &'a str },
ImageModel(&'a str),
TranscriptionModel(&'a str),
TranscribableAudio(&'a str),
ExtractableDocument { media_type: &'a str, file_name: &'a str },
}
pub enum ManagedObjectArguments<'a> {
RustBinary(&'a serde_json::Value),
WebLibraryAttachment(&'a serde_json::Value),
}
pub fn decode(
tool: &str,
value: &serde_json::Value,
) -> anyhow::Result<Option<DecodedTool>>;
pub fn validate(request: ValidationRequest<'_>) -> anyhow::Result<()>;
pub fn decode_managed_objects(
request: ManagedObjectArguments<'_>,
) -> anyhow::Result<Vec<String>>;
```
`decode` rejects missing, extra, wrongly typed, duplicate, malformed, or out-of-range arguments in compatibility-sensitive order. It returns `Ok(None)` for tools owned by another subsystem. Node and delivery IDs are validated by their authoritative types.
Media models, MIME types, and document formats use exact allowlists. `TranscribeAudio` and `AnnotateMedia` prompts must be nonblank but have no length ceiling and are returned unchanged. The current `TranscribeAudio` contract rejects every optional field, including `temperature`.
`decode_managed_objects` validates only object arguments consumed by managed-source calls. None of these operations grants authority or performs I/O.