ADR-018-v4: CODI Dynamic Command Architecture - Part 2 (Technical)
Document Specification Block​
Document: ADR-018-v4-codi-dynamic-command-architecture-part2-technical
Version: 1.0.0
Purpose: Constrain AI implementation with exact technical specifications for dynamic command loading
Audience: AI agents, developers implementing the system
Date Created: 2025-09-01
Date Modified: 2025-09-01
QA Review Date: Pending
Status: DRAFT
Table of Contents​
- Constraints
- Dependencies
- Component Architecture
- Data Models
- Implementation Patterns
- API Specifications
- Testing Requirements
- Performance Benchmarks
- Security Controls
- Logging and Error Handling
- References
- Approval Signatures
1. Constraints​
CONSTRAINT: Binary Size​
Core CODI binary MUST be under 5MB with exactly 8-10 built-in commands.
CONSTRAINT: Load Performance​
Dynamic libraries MUST load in under 250ms first time, execute from cache in under 105ms.
CONSTRAINT: Cross-Platform​
MUST work identically on Cloud Run, Browser WASM, and local environments.
CONSTRAINT: Offline Capability​
MUST function offline after initial library load with persistent cache.
CONSTRAINT: Security​
All dynamic libraries MUST be cryptographically signed and sandboxed.
2. Dependencies​
cargo.toml Dependencies​
[dependencies]
# Core async and CLI
tokio = { version = "1.35", features = ["full"] }
clap = { version = "4.4", features = ["derive", "env"] }
# Storage
sqlx = { version = "0.7", features = ["runtime-tokio-rustls", "sqlite"] }
rusqlite = { version = "0.30", features = ["bundled"] }
# Serialization
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
bincode = "1.3"
# Compression
zstd = "0.13"
flate2 = "1.0"
# Security
ring = "0.17"
ed25519-dalek = "2.1"
sha2 = "0.10"
# Networking
reqwest = { version = "0.11", features = ["json", "rustls-tls"] }
tokio-tungstenite = "0.20"
# Utilities
anyhow = "1.0"
thiserror = "1.0"
tracing = "0.1"
dirs = "5.0"
uuid = { version = "1.6", features = ["v4", "serde"] }
chrono = { version = "0.4", features = ["serde"] }
# WASM support
[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = "0.2"
web-sys = "0.3"
js-sys = "0.3"
3. Component Architecture​
// File: src/main.rs
use clap::{Command, Arg};
use std::sync::Arc;
use anyhow::Result;
const BUILT_IN_COMMANDS: &[&str] = &[
"auth", "log", "config", "help",
"connect", "sync", "session", "mcp"
];
#[tokio::main]
async fn main() -> Result<()> {
let app = build_cli();
let matches = app.get_matches();
match matches.subcommand() {
Some((cmd, args)) if BUILT_IN_COMMANDS.contains(&cmd) => {
handle_builtin_command(cmd, args).await
}
Some((cmd, args)) => {
handle_dynamic_command(cmd, args).await
}
None => show_dynamic_help().await,
}
}
// File: src/loader/mod.rs
pub struct DynamicLoader {
cache: Arc<SqliteCache>,
client: Arc<LibraryClient>,
runtime_mode: RuntimeMode,
validator: Arc<SecurityValidator>,
}
impl DynamicLoader {
pub async fn new() -> Result<Self> {
let runtime_mode = RuntimeMode::detect();
let cache = SqliteCache::init(runtime_mode.clone()).await?;
Ok(Self {
cache: Arc::new(cache),
client: Arc::new(LibraryClient::new()),
runtime_mode,
validator: Arc::new(SecurityValidator::new()),
})
}
pub async fn load_command(&self, command: &str) -> Result<CommandLibrary> {
// Extract library name from command
let library_name = command.split('.').next()
.ok_or_else(|| anyhow!("Invalid command format"))?;
// Check cache first
if let Some(lib) = self.cache.get_library(library_name).await? {
if !lib.is_expired() {
tracing::debug!("Cache hit for library: {}", library_name);
return Ok(lib);
}
}
// Fetch from server
tracing::info!("Fetching library: {}", library_name);
let library_data = self.client
.fetch_library(library_name)
.await?;
// Validate security
self.validator.validate(&library_data).await?;
// Store in cache
self.cache.store_library(&library_data).await?;
Ok(CommandLibrary::from_data(library_data)?)
}
}
4. Data Models​
Command Library Format​
// File: src/models/library.rs
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LibraryManifest {
pub library: LibraryMetadata,
pub commands: HashMap<String, CommandDefinition>,
#[serde(skip_serializing_if = "Option::is_none")]
pub wasm_module: Option<WasmModule>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LibraryMetadata {
pub name: String,
pub version: String,
pub description: String,
pub permissions: Vec<String>,
pub dependencies: Vec<String>,
pub signature: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CommandDefinition {
pub description: String,
pub subcommands: HashMap<String, SubcommandDefinition>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SubcommandDefinition {
pub description: String,
pub arguments: Vec<ArgumentDefinition>,
pub options: Vec<OptionDefinition>,
pub handler: HandlerDefinition,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HandlerDefinition {
#[serde(rename = "type")]
pub handler_type: HandlerType,
pub endpoint: Option<String>,
pub function: Option<String>,
pub fallback: Option<Box<HandlerDefinition>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum HandlerType {
WebSocket,
Wasm,
Local,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WasmModule {
pub format: WasmFormat,
pub data: String, // Base64 encoded
pub exports: Vec<String>,
}
Storage Models​
// File: src/models/storage.rs
#[derive(Debug, Clone)]
pub struct LibraryData {
pub id: String,
pub version: String,
pub json: Vec<u8>, // Compressed JSON
pub loaded_at: i64,
pub expires_at: Option<i64>,
pub size_bytes: i64,
pub hash: String,
}
#[derive(Debug, Clone, PartialEq)]
pub enum RuntimeMode {
CloudRun,
Wasm,
Local,
}
impl RuntimeMode {
pub fn detect() -> Self {
if std::env::var("K_SERVICE").is_ok() {
RuntimeMode::CloudRun
} else if cfg!(target_arch = "wasm32") {
RuntimeMode::Wasm
} else {
RuntimeMode::Local
}
}
pub fn cache_path(&self) -> std::path::PathBuf {
match self {
RuntimeMode::CloudRun => {
std::path::PathBuf::from("/var/lib/codi/cache.db")
}
RuntimeMode::Local => {
dirs::data_dir()
.expect("Could not find data directory")
.join("coditect")
.join("codi")
.join("cache.db")
}
RuntimeMode::Wasm => {
// Not used in WASM
std::path::PathBuf::from(":memory:")
}
}
}
}
5. Implementation Patterns​
Cache Implementation​
// File: src/storage/sqlite_cache.rs
use sqlx::{SqlitePool, sqlite::SqlitePoolOptions};
use anyhow::Result;
pub struct SqliteCache {
pool: SqlitePool,
runtime_mode: RuntimeMode,
}
impl SqliteCache {
pub async fn init(mode: RuntimeMode) -> Result<Self> {
let db_path = mode.cache_path();
// Ensure directory exists
if let Some(parent) = db_path.parent() {
std::fs::create_dir_all(parent)?;
}
let pool = SqlitePoolOptions::new()
.max_connections(5)
.connect(&format!("sqlite:{}", db_path.display()))
.await?;
// Initialize schema
sqlx::query!(
r#"
CREATE TABLE IF NOT EXISTS command_libraries (
id TEXT NOT NULL,
version TEXT NOT NULL,
library_json BLOB NOT NULL,
metadata TEXT NOT NULL,
loaded_at INTEGER NOT NULL,
expires_at INTEGER,
size_bytes INTEGER NOT NULL,
hash TEXT NOT NULL,
PRIMARY KEY (id, version)
);
CREATE INDEX IF NOT EXISTS idx_library_loaded
ON command_libraries(loaded_at);
"#
)
.execute(&pool)
.await?;
Ok(Self { pool, runtime_mode: mode })
}
pub async fn get_library(&self, name: &str) -> Result<Option<CommandLibrary>> {
let row = sqlx::query!(
r#"
SELECT library_json, loaded_at, expires_at
FROM command_libraries
WHERE id = ?
ORDER BY version DESC
LIMIT 1
"#,
name
)
.fetch_optional(&self.pool)
.await?;
match row {
Some(r) => {
let decompressed = zstd::decode_all(&r.library_json[..])?;
let manifest: LibraryManifest = serde_json::from_slice(&decompressed)?;
Ok(Some(CommandLibrary {
manifest,
loaded_at: r.loaded_at,
expires_at: r.expires_at,
}))
}
None => Ok(None),
}
}
pub async fn store_library(&self, data: &LibraryData) -> Result<()> {
let compressed = zstd::encode_all(&data.json[..], 3)?;
let metadata = serde_json::to_string(&data)?;
sqlx::query!(
r#"
INSERT OR REPLACE INTO command_libraries
(id, version, library_json, metadata, loaded_at, expires_at, size_bytes, hash)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
"#,
data.id,
data.version,
compressed,
metadata,
data.loaded_at,
data.expires_at,
data.size_bytes,
data.hash
)
.execute(&self.pool)
.await?;
Ok(())
}
}
WASM Storage Implementation​
// File: src/storage/wasm_storage.rs
#[cfg(target_arch = "wasm32")]
mod wasm_impl {
use wasm_bindgen::prelude::*;
use web_sys::{window, Storage};
pub struct WasmStorage {
local_storage: Storage,
}
impl WasmStorage {
pub fn new() -> Result<Self, JsValue> {
let window = window().ok_or("No window object")?;
let local_storage = window
.local_storage()?
.ok_or("No local storage")?;
Ok(Self { local_storage })
}
pub async fn get_library(&self, name: &str) -> Result<Option<CommandLibrary>, JsValue> {
let key = format!("codi_lib_{}", name);
match self.local_storage.get_item(&key)? {
Some(data) => {
let manifest: LibraryManifest = serde_json::from_str(&data)
.map_err(|e| JsValue::from_str(&e.to_string()))?;
Ok(Some(CommandLibrary::from_manifest(manifest)))
}
None => Ok(None),
}
}
pub async fn store_library(&self, name: &str, data: &str) -> Result<(), JsValue> {
let key = format!("codi_lib_{}", name);
self.local_storage.set_item(&key, data)?;
Ok(())
}
}
}
Command Execution​
// File: src/executor/mod.rs
use async_trait::async_trait;
#[async_trait]
pub trait CommandExecutor {
async fn execute(&self, args: &CommandArgs) -> Result<CommandOutput>;
}
pub struct DynamicExecutor {
loader: Arc<DynamicLoader>,
websocket: Arc<WebSocketClient>,
wasm_runtime: Arc<WasmRuntime>,
}
impl DynamicExecutor {
pub async fn execute_command(
&self,
command: &str,
args: Vec<String>,
) -> Result<String> {
// Load library if needed
let library = self.loader.load_command(command).await?;
// Parse command structure
let (cmd_name, subcmd_name) = parse_command_path(command)?;
// Find command definition
let cmd_def = library.manifest.commands
.get(cmd_name)
.ok_or_else(|| anyhow!("Command not found: {}", cmd_name))?;
let subcmd_def = cmd_def.subcommands
.get(subcmd_name)
.ok_or_else(|| anyhow!("Subcommand not found: {}", subcmd_name))?;
// Execute based on handler type
match &subcmd_def.handler.handler_type {
HandlerType::WebSocket => {
self.execute_websocket(&subcmd_def.handler, args).await
}
HandlerType::Wasm => {
self.execute_wasm(&library, &subcmd_def.handler, args).await
}
HandlerType::Local => {
self.execute_local(&subcmd_def.handler, args).await
}
}
}
}
6. API Specifications​
Library Server API​
// File: src/api/library_server.rs
use actix_web::{web, HttpResponse, Result};
#[get("/api/v1/libraries/{name}")]
pub async fn get_library(
path: web::Path<String>,
auth: BearerAuth,
) -> Result<HttpResponse> {
let library_name = path.into_inner();
// Validate permissions
if !auth.has_permission(&format!("library:{}", library_name)) {
return Ok(HttpResponse::Forbidden().json(json!({
"error": "insufficient_permissions"
})));
}
// Load library manifest
let manifest = load_library_manifest(&library_name).await?;
// Sign the manifest
let signature = sign_library(&manifest)?;
Ok(HttpResponse::Ok()
.insert_header(("X-Library-Signature", signature))
.json(&manifest))
}
#[get("/api/v1/libraries")]
pub async fn list_libraries(
query: web::Query<ListQuery>,
auth: BearerAuth,
) -> Result<HttpResponse> {
let libraries = list_available_libraries(
query.filter.as_deref(),
query.offset.unwrap_or(0),
query.limit.unwrap_or(50),
).await?;
Ok(HttpResponse::Ok().json(&libraries))
}
7. Testing Requirements​
Test Coverage Requirements​
- Unit Test Coverage: ≥95% of loader and cache logic
- Integration Test Coverage: ≥90% of all storage backends
- E2E Test Coverage: All platforms (Cloud Run, WASM, Local)
- Performance Test Coverage: Load time benchmarks
- Security Test Coverage: Signature validation, sandbox tests
Integration Tests​
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_library_loading_performance() {
let loader = DynamicLoader::new().await.unwrap();
// First load from server
let start = std::time::Instant::now();
let lib = loader.load_command("prompt.generate").await.unwrap();
let first_load = start.elapsed();
assert!(first_load.as_millis() < 250);
assert_eq!(lib.manifest.library.name, "prompt-engineering");
// Second load from cache
let start = std::time::Instant::now();
let lib2 = loader.load_command("prompt.test").await.unwrap();
let cached_load = start.elapsed();
assert!(cached_load.as_millis() < 105);
}
#[tokio::test]
async fn test_offline_capability() {
let loader = DynamicLoader::new().await.unwrap();
// Load library while online
loader.load_command("agent.list").await.unwrap();
// Simulate offline
loader.client.set_offline_mode(true);
// Should work from cache
let lib = loader.load_command("agent.create").await.unwrap();
assert_eq!(lib.manifest.library.name, "agent-ops");
}
#[tokio::test]
async fn test_multi_environment_storage() {
// Test Cloud Run
std::env::set_var("K_SERVICE", "test-service");
let mode = RuntimeMode::detect();
assert_eq!(mode, RuntimeMode::CloudRun);
let cache = SqliteCache::init(mode).await.unwrap();
let path = cache.runtime_mode.cache_path();
assert!(path.starts_with("/var/lib/codi"));
// Test Local
std::env::remove_var("K_SERVICE");
let mode = RuntimeMode::detect();
assert_eq!(mode, RuntimeMode::Local);
}
}
8. Performance Benchmarks​
Required Metrics​
const MAX_BINARY_SIZE_MB: usize = 5;
const MAX_STARTUP_TIME_MS: u64 = 100;
const MAX_FIRST_LOAD_MS: u64 = 250;
const MAX_CACHED_EXEC_MS: u64 = 105;
const MAX_MEMORY_IDLE_MB: usize = 30;
pub struct PerformanceValidator {
pub async fn validate_performance(&self) -> Result<ValidationReport> {
let mut report = ValidationReport::default();
// Binary size check
let binary_size = std::fs::metadata("target/release/codi")?.len();
report.binary_size_ok = binary_size <= (MAX_BINARY_SIZE_MB * 1024 * 1024) as u64;
// Startup time
let start = Instant::now();
Command::new("./codi").arg("help").output()?;
report.startup_time_ok = start.elapsed().as_millis() <= MAX_STARTUP_TIME_MS as u128;
// First load time
let start = Instant::now();
self.loader.load_command("new_command").await?;
report.first_load_ok = start.elapsed().as_millis() <= MAX_FIRST_LOAD_MS as u128;
Ok(report)
}
}
9. Security Controls​
Library Validation​
// File: src/security/validator.rs
use ed25519_dalek::{PublicKey, Signature, Verifier};
pub struct SecurityValidator {
trusted_keys: Vec<PublicKey>,
sandbox: WasmSandbox,
}
impl SecurityValidator {
pub async fn validate(&self, library_data: &LibraryData) -> Result<()> {
// Verify hash
let computed_hash = self.compute_hash(&library_data.json)?;
if computed_hash != library_data.hash {
return Err(SecurityError::HashMismatch);
}
// Verify signature
let manifest: LibraryManifest = serde_json::from_slice(&library_data.json)?;
self.verify_signature(&manifest)?;
// Check permissions
self.validate_permissions(&manifest.library.permissions)?;
// Sandbox WASM if present
if let Some(wasm) = &manifest.wasm_module {
self.sandbox.validate_module(wasm)?;
}
Ok(())
}
fn verify_signature(&self, manifest: &LibraryManifest) -> Result<()> {
let signature = Signature::from_bytes(
&hex::decode(&manifest.library.signature)?
)?;
let message = self.canonical_json(manifest)?;
for key in &self.trusted_keys {
if key.verify(&message, &signature).is_ok() {
return Ok(());
}
}
Err(SecurityError::InvalidSignature)
}
}
10. Logging and Error Handling​
Logging Requirements​
// File: src/logging/mod.rs
use tracing::{info, warn, error, instrument};
#[instrument(skip(self))]
pub async fn log_library_load(&self, library: &str, cached: bool, duration: Duration) {
info!(
library = %library,
cached = cached,
duration_ms = duration.as_millis(),
storage_type = ?self.runtime_mode,
"Library loaded"
);
}
#[instrument(skip(self))]
pub async fn log_cache_operation(&self, operation: &str, success: bool) {
if success {
info!(
operation = operation,
cache_size = self.get_cache_size().await,
"Cache operation successful"
);
} else {
warn!(
operation = operation,
"Cache operation failed"
);
}
}
Error Handling​
#[derive(thiserror::Error, Debug)]
pub enum DynamicLoaderError {
#[error("Library not found: {0}")]
LibraryNotFound(String),
#[error("Network error downloading library")]
NetworkError(#[from] reqwest::Error),
#[error("Cache corrupted, rebuilding required")]
CacheCorrupted,
#[error("Security validation failed: {0}")]
SecurityError(String),
#[error("Storage error: {0}")]
StorageError(#[from] sqlx::Error),
}
11. References​
- ADR-009-v4: CODI Command Interface
- ADR-016-v4: CODI Rust Implementation
- ADR-001-v4: Container Execution
- ADR-002-v4: Storage Architecture
- LOGGING-STANDARD-v4
Version Compatibility​
- Rust: 1.75+ for async traits
- SQLite: 3.35+ for JSON functions
- WASM: wasm32-unknown-unknown target
12. Approval Signatures​
Technical Sign-off​
| Component | Owner | Approved | Date |
|---|---|---|---|
| Architecture | Session5 | ✓ | 2025-09-01 |
| Implementation | Pending | - | - |
| Security Review | Pending | - | - |
| Performance Test | Pending | - | - |
Implementation Checklist​
- Core binary under 5MB
- 8 built-in commands implemented
- Dynamic loader functional
- SQLite cache working
- WASM storage implemented
- Security validation complete
- Performance benchmarks met
- Cross-platform tested