Skip to main content

Architecture Explorer

Interactive Diagrams

Click on any component in the diagrams below to jump to its detailed documentation. Use the "Zoom In" sections to explore each subsystem in depth.

System Overview

The top-level view of ClawDesk — from external messaging platforms through the gateway to LLM providers.


Crate Dependency Graph

The full 27-crate dependency DAG. Arrows point from dependant → dependency (i.e., "uses").

Reading the DAG

The crate dependency graph follows a strict layering rule:

$$ \text{Layer}(A) > \text{Layer}(B) \Rightarrow A \text{ may depend on } B $$ $$ \text{Layer}(A) \leq \text{Layer}(B) \Rightarrow A \text{ must NOT depend on } B $$

LayerCratesDepends on
0typesNothing
1storageLayer 0
2domainLayers 0–1
3channel, sochdbLayers 0–2
4channels, agents, skills, memory, securityLayers 0–3
5providersLayers 0–4
6gatewayLayers 0–5
7acpLayers 0–6
8cli, tauriLayers 0–7

Message Flow View

The complete data transformation pipeline for a single message.

Zoom In: Type Transformations

The key insight is the funnel pattern:

  1. 13 shapes in — each platform has unique fields
  2. 1 shape outNormalizedMessage is the universal representation
// 13 platform-specific shapes...
enum InboundMessage {
Telegram(TelegramInbound), // chat_id, reply_to, media_group
Discord(DiscordInbound), // guild_id, channel_id, embeds
Slack(SlackInbound), // team_id, thread_ts, blocks
// ... 10 more variants
}

// ...funneled into 1 canonical shape
struct NormalizedMessage {
channel_id: ChannelId,
conversation_id: ConversationId,
sender: Option<Sender>,
content: Content,
thread_id: Option<ThreadId>,
timestamp: DateTime<Utc>,
metadata: Metadata,
}

See the Type Algebra Deep Dive for the full mathematical analysis.

Zoom In: Pipeline Stages
StageCrateInputOutputMay Fail?
1clawdesk-securityNormalizedMessageAuthContextYes (blocked user)
2clawdesk-memoryNormalizedMessage + AuthContextVec<HistoryEntry>Yes (storage)
3clawdesk-agentsHistory + AuthGuardedContextYes (over budget)
4clawdesk-skillsContext + BudgetVec<SelectedSkill>No (empty is valid)
5clawdesk-providersRequestProviderResponseYes (LLM error)
6clawdesk-providersResponse/ErrorFinal responseYes (all exhausted)

Stages are sequential but substages (like parallel tool execution in Stage 5) use JoinSet. See Structured Concurrency.


Security Layer View

The 4-layer security cascade that processes every message and tool call.

Zoom In: Content Scanning (Layer 2)

The three scanning stages run in sequence, each progressively more expensive:

StageMethodSpeedCatches
RegexPattern matching~1μsKnown malicious patterns, PII
ASTStructural analysis~100μsCode injection, prompt injection
SemanticML-based analysis~10msNovel attacks, context-dependent threats
pub async fn scan(content: &str) -> ScanResult {
// Fast regex first (eliminates most benign content)
if let Some(finding) = regex_scan(content) {
return ScanResult::Blocked(finding);
}

// AST analysis for structured attacks
if let Some(finding) = ast_scan(content).await {
return ScanResult::Blocked(finding);
}

// Semantic analysis only for content that passed regex+AST
if let Some(finding) = semantic_scan(content).await {
return ScanResult::Flagged(finding);
}

ScanResult::Clean
}

This cascade is deliberately ordered: cheap checks first, expensive checks only if needed. ~95% of messages are cleared by the regex stage alone.


Channel Trait Layers

The layered capability model for channels.

Zoom In: Capability Detection

At runtime, the gateway checks whether a channel supports a capability before using it:

// Check if channel supports streaming
if let Some(streaming) = channel.as_streaming() {
streaming.send_stream(&conv_id, response_stream).await?;
} else {
// Fall back to collecting the stream and sending as a single message
let full = collect_stream(response_stream).await;
channel.send(full).await?;
}

This is Rust's trait object downcasting — compile-time safe, zero runtime overhead for channels that don't support a capability.


Fallback FSM View

The provider fallback state machine (see Fallback FSM Deep Dive for the full analysis).

Zoom In: Error Classification
ErrorClassificationFSM Action
429 Rate LimitTransientRetry after backoff
500 Server ErrorTransientRetry once, then next provider
401 Auth ErrorFatalAbort immediately
Context too longRecoverableTry next provider
Network timeoutTransientRetry once

The FSM terminates in at most $2n + 1$ transitions where $n$ is the number of candidate providers.


DiagramDeep DiveTutorial
System OverviewArchitecture OverviewMessage Flow
Crate DAGCrate Dependency Graph
Message FlowType AlgebraBuild a Channel
SecuritySecurity Model
Channel TraitsChannel TraitsBuild a Channel
Fallback FSMFallback FSMBuild a Provider