# Portfolio IA: Especificaciones Técnicas para Desarrolladores ## Arquitectura del Ecosistema ```text ┌─────────────────────────────────────────────────────────────────────────────┐ │ CAPA DE PRESENTACIÓN │ ├─────────────────────────────────────────────────────────────────────────────┤ │ Leptos WASM (Vapora UI) │ Ratatui TUI │ Axum REST │ CLI (clap) │ └─────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ CAPA DE ORQUESTACIÓN │ ├─────────────────────────────────────────────────────────────────────────────┤ │ Vapora Coordinator │ TypeDialog Backends │ Provisioning Orchestrator │ │ (NATS JetStream) │ (BackendFactory) │ (Rust/Nushell hybrid) │ └─────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ CAPA DE CONOCIMIENTO │ ├─────────────────────────────────────────────────────────────────────────────┤ │ Kogral Knowledge Graph │ Vapora Learning Profiles │ Provisioning RAG │ │ (6 node types) │ (expertise + recency) │ (1200+ docs) │ └─────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ CAPA DE PERSISTENCIA │ ├─────────────────────────────────────────────────────────────────────────────┤ │ SurrealDB (multi-tenant scopes) │ Filesystem (git-native markdown) │ │ NATS JetStream (mensajería) │ Redis (vector stores opcionales) │ │ etcd (SecretumVault HA) │ PostgreSQL (vault enterprise) │ └─────────────────────────────────────────────────────────────────────────────┘ ``` --- ## 1. Vapora: Especificaciones ### Workspace Structure ```text crates/ ├── vapora-shared/ # Core: models, errors, types ├── vapora-backend/ # Axum REST API (40+ endpoints) ├── vapora-agents/ # Agent orchestration + learning ├── vapora-llm-router/ # Multi-provider routing + budget ├── vapora-swarm/ # Swarm coordination + metrics ├── vapora-knowledge-graph/# Temporal KG + learning curves ├── vapora-frontend/ # Leptos WASM UI ├── vapora-mcp-server/ # MCP protocol gateway ├── vapora-tracking/ # Task/project storage ├── vapora-telemetry/ # OpenTelemetry integration ├── vapora-analytics/ # Event pipeline ├── vapora-worktree/ # Git worktree management └── vapora-doc-lifecycle/ # Documentation management ``` ### Core Types ```rust // vapora-shared/src/models.rs pub struct Agent { pub id: String, pub role: AgentRole, // 12 roles disponibles pub status: AgentStatus, // Ready | Busy | Offline pub provider: LLMProvider, // Claude | OpenAI | Gemini | Ollama pub last_heartbeat: DateTime, } pub enum AgentRole { Architect, Developer, CodeReviewer, Tester, Documenter, Marketer, Presenter, DevOps, Monitor, Security, ProjectManager, DecisionMaker, } // vapora-agents/src/learning_profile.rs pub struct ExpertiseProfile { pub task_type: String, pub success_rate: f64, pub avg_duration: Duration, pub execution_count: u32, pub recent_weight: f64, // 3x for last 7 days pub confidence: f64, // prevents overfitting on small samples } // Scoring formula fn calculate_score(load: f64, expertise: f64, confidence: f64) -> f64 { 0.3 * load + 0.5 * expertise + 0.2 * confidence } ``` ### LLM Router Configuration ```rust // vapora-llm-router/src/config.rs pub struct RoutingRule { pub pattern: String, // regex para task type pub provider: LLMProvider, pub model: String, pub fallback_chain: Vec, } pub struct BudgetConfig { pub role: AgentRole, pub monthly_limit_cents: u32, pub weekly_limit_cents: Option, pub enforcement: BudgetEnforcement, // Normal | NearThreshold | Exceeded } // Cost tracking per request pub struct CostRecord { pub provider: LLMProvider, pub model: String, pub input_tokens: u32, pub output_tokens: u32, pub cost_cents: f64, pub task_type: String, pub timestamp: DateTime, } ``` ### API Endpoints (Axum) ```rust // vapora-backend/src/api/mod.rs Router::new() // Projects .route("/projects", get(list_projects).post(create_project)) .route("/projects/:id", get(get_project).put(update_project).delete(delete_project)) // Tasks .route("/tasks", get(list_tasks).post(create_task)) .route("/tasks/:id/assign", post(assign_to_agent)) // Agents .route("/agents", get(list_agents)) .route("/agents/:id/health", get(agent_health)) .route("/agents/:role/expertise", get(role_expertise)) // LLM Router .route("/llm/route", post(route_request)) .route("/llm/budget/:role", get(get_budget).put(set_budget)) .route("/llm/costs", get(cost_report)) // Swarm .route("/swarm/assign", post(assign_task)) .route("/swarm/status", get(swarm_status)) // Metrics .route("/metrics", get(prometheus_metrics)) ``` ### NATS Message Types ```rust // vapora-agents/src/messages.rs #[derive(Serialize, Deserialize)] pub enum AgentMessage { TaskAssignment { task_id: String, agent_id: String, task_type: String, payload: serde_json::Value, }, TaskResult { task_id: String, agent_id: String, status: TaskStatus, output: Option, duration_ms: u64, tokens_used: u32, }, Heartbeat { agent_id: String, status: AgentStatus, current_load: f64, }, } // Subjects const TASK_ASSIGNMENT: &str = "vapora.tasks.assign"; const TASK_RESULTS: &str = "vapora.tasks.results"; const AGENT_HEARTBEAT: &str = "vapora.agents.heartbeat"; ``` --- ## 2. Kogral: Especificaciones ### Workspace Structure ``` crates/ ├── kogral-core/ # Core library (models, storage, query) ├── kogral-cli/ # CLI (13 commands) └── kogral-mcp/ # MCP server for Claude Code ``` ### Node Types ```rust // kogral-core/src/models.rs #[derive(Debug, Clone, Serialize, Deserialize)] pub enum NodeType { Note, // General notes Decision, // ADRs (Architectural Decision Records) Guideline, // Team/org standards Pattern, // Reusable solutions Journal, // Daily development log Execution, // Agent execution records } #[derive(Debug, Clone, Serialize, Deserialize)] pub enum RelationType { RelatesTo, DependsOn, Implements, Extends, Supersedes, Explains, } pub struct Node { pub id: String, pub node_type: NodeType, pub title: String, pub content: String, // Markdown body pub metadata: HashMap, pub tags: Vec, pub created_at: DateTime, pub updated_at: DateTime, } pub struct Edge { pub source: String, // Node ID pub target: String, // Node ID pub relation: RelationType, pub weight: f64, // Relationship strength } ``` ### Storage Backends ```rust // kogral-core/src/storage/mod.rs #[async_trait] pub trait Storage: Send + Sync { async fn create_node(&self, node: &Node) -> Result; async fn get_node(&self, id: &str) -> Result>; async fn update_node(&self, node: &Node) -> Result<()>; async fn delete_node(&self, id: &str) -> Result<()>; async fn list_nodes(&self, filter: NodeFilter) -> Result>; async fn create_edge(&self, edge: &Edge) -> Result<()>; async fn get_edges(&self, node_id: &str) -> Result>; async fn delete_edge(&self, source: &str, target: &str) -> Result<()>; async fn search(&self, query: &str, limit: usize) -> Result>; async fn semantic_search(&self, embedding: &[f32], limit: usize) -> Result>; } // Implementations pub struct FilesystemStorage { /* .kogral/ directory */ } pub struct SurrealDbStorage { /* SurrealDB connection */ } pub struct MemoryStorage { /* DashMap for testing */ } ``` ### Embedding Configuration ```rust // kogral-core/src/embeddings.rs pub enum EmbeddingProvider { FastEmbed { model: String, // "BAAI/bge-small-en-v1.5" dimensions: usize, // 384 }, OpenAI { model: String, // "text-embedding-3-small" api_key: String, }, Ollama { model: String, url: String, }, } #[async_trait] pub trait Embedder: Send + Sync { async fn embed(&self, text: &str) -> Result>; async fn embed_batch(&self, texts: &[String]) -> Result>>; fn dimensions(&self) -> usize; } ``` ### MCP Server Tools ```rust // kogral-mcp/src/tools.rs pub const MCP_TOOLS: &[Tool] = &[ Tool { name: "search", description: "Search knowledge graph by text or semantic similarity", parameters: json!({ "query": { "type": "string" }, "node_type": { "type": "string", "optional": true }, "limit": { "type": "integer", "default": 10 } }), }, Tool { name: "add_note", description: "Add a new note to the knowledge graph", parameters: json!({ "title": { "type": "string" }, "content": { "type": "string" }, "tags": { "type": "array", "items": { "type": "string" } } }), }, Tool { name: "add_decision", description: "Record an architectural decision (ADR)", parameters: json!({ "title": { "type": "string" }, "context": { "type": "string" }, "decision": { "type": "string" }, "consequences": { "type": "string" } }), }, Tool { name: "link", description: "Create relationship between nodes", parameters: json!({ "source_id": { "type": "string" }, "target_id": { "type": "string" }, "relation": { "type": "string", "enum": ["relates_to", "depends_on", "implements", "extends", "supersedes", "explains"] } }), }, Tool { name: "get_guidelines", description: "Get applicable guidelines for a topic", parameters: json!({ "topic": { "type": "string" }, "include_shared": { "type": "boolean", "default": true } }), }, Tool { name: "list_graphs", description: "List available knowledge graphs", parameters: json!({}), }, Tool { name: "export", description: "Export knowledge graph to format", parameters: json!({ "format": { "type": "string", "enum": ["markdown", "json", "yaml"] }, "filter": { "type": "object", "optional": true } }), }, ]; ``` ### CLI Commands ```bash # kogral-cli commands kogral init # Initialize .kogral/ directory kogral add note # Add note interactively kogral add decision <title> # Add ADR with guided prompts kogral search <query> # Text search kogral search --semantic <q> # Semantic search kogral link <src> <dst> <rel> # Create relationship kogral list [--type <type>] # List nodes kogral show <id> # Display node details kogral delete <id> # Remove node kogral graph # Visualize graph (DOT format) kogral sync # Sync filesystem ↔ SurrealDB kogral serve # Start MCP server kogral import <path> # Import from Logseq/markdown kogral export <format> # Export to markdown/json kogral config # Show/edit configuration ``` --- ## 3. TypeDialog: Especificaciones ### Workspace Structure ```text crates/ ├── typedialog-core/ # Core (forms, backends, validation) ├── typedialog/ # CLI binary ├── typedialog-tui/ # TUI binary (ratatui) ├── typedialog-web/ # Web binary (axum) ├── typedialog-ai/ # AI backend (RAG, embeddings) ├── typedialog-agent/ │ ├── typedialog-ag-core/ # Agent runtime │ └── typedialog-ag/ # Agent CLI └── typedialog-prov-gen/ # IaC generation ``` ### Form Definition (TOML) ```toml # employee_onboarding.toml [form] id = "employee_onboarding" version = "1.0.0" title = "Employee Onboarding" description = "New employee registration form" [[sections]] id = "personal" title = "Personal Information" [[sections.fields]] id = "full_name" type = "text" label = "Full Name" required = true validation.min_length = 2 validation.max_length = 100 [[sections.fields]] id = "department" type = "select" label = "Department" required = true options = [ { value = "engineering", label = "Engineering" }, { value = "product", label = "Product" }, { value = "design", label = "Design" }, ] [[sections.fields]] id = "skills" type = "multi-select" label = "Skills" display_mode = "grid" options = [ { value = "rust", label = "Rust" }, { value = "typescript", label = "TypeScript" }, { value = "python", label = "Python" }, ] [[sections.fields]] id = "start_date" type = "date" label = "Start Date" default = "today" [output] format = "json" validation = "nickel://schemas/employee.ncl" ``` ### Backend Trait ```rust // typedialog-core/src/backend.rs #[async_trait] pub trait Backend: Send + Sync { fn name(&self) -> &str; async fn execute(&self, form: &Form) -> Result<FormResponse>; async fn render_field(&self, field: &Field, value: Option<&Value>) -> Result<Value>; fn supports_streaming(&self) -> bool { false } } pub struct BackendFactory; impl BackendFactory { pub fn create(backend_type: BackendType) -> Box<dyn Backend> { match backend_type { BackendType::Cli => Box::new(CliBackend::new()), BackendType::Tui => Box::new(TuiBackend::new()), BackendType::Web => Box::new(WebBackend::new()), BackendType::Ai => Box::new(AiBackend::new()), BackendType::Agent => Box::new(AgentBackend::new()), BackendType::ProvGen => Box::new(ProvGenBackend::new()), } } } ``` ### Agent MDX Format ```mdx --- name: code_reviewer version: "1.0" provider: claude model: claude-sonnet-4-20250514 temperature: 0.3 max_tokens: 4096 --- # Code Review Agent ## System Prompt You are an expert code reviewer. Review the following code for: - Security vulnerabilities - Performance issues - Code style and best practices - Potential bugs ## Template Variables - `{{language}}`: Programming language - `{{code}}`: Code to review - `{{guidelines}}`: Project-specific guidelines ## User Prompt Review this {{language}} code: ` ` `{{language}} {{code}} ` ` ` Project guidelines: {{guidelines}} Provide a structured review with severity levels (critical, warning, info). ## Output Validation format: json schema: | { "issues": [{ "severity": "critical | warning | info", "line": number, "message": string, "suggestion": string }], "summary": string } ``` ### Nickel Contract Integration ```rust // typedialog-core/src/nickel.rs pub struct NickelValidator { runtime: nickel_lang_core::eval::Runtime, } impl NickelValidator { pub fn validate(&self, data: &Value, contract_path: &str) -> Result<ValidationResult> { let contract = self.runtime.load(contract_path)?; let result = self.runtime.eval_with_contract(data, contract)?; Ok(result) } pub fn extract_schema(&self, contract_path: &str) -> Result<FormSchema> { // Parse Nickel contract and generate form schema let contract = self.runtime.load(contract_path)?; FormSchema::from_nickel_contract(&contract) } } ``` ### Prov-Gen Output ```rust // typedialog-prov-gen/src/generator.rs pub enum CloudProvider { Aws, Gcp, Azure, Hetzner, UpCloud, Lxd, } pub struct InfrastructureConfig { pub provider: CloudProvider, pub region: String, pub resources: Vec<Resource>, pub networking: NetworkConfig, pub security: SecurityConfig, } pub struct Generator { templates: tera::Tera, validators: Vec<Box<dyn Validator>>, // 7-layer validation } impl Generator { pub async fn generate(&self, config: &InfrastructureConfig) -> Result<GeneratedIaC> { // 1. Validate input config self.validate_config(config)?; // 2. Load provider-specific templates let template = self.templates.get_template(&format!("{}.ncl.tera", config.provider))?; // 3. Render Nickel configuration let nickel_code = template.render(&config)?; // 4. Validate generated Nickel self.validate_nickel(&nickel_code)?; Ok(GeneratedIaC { provider: config.provider, code: nickel_code, files: self.split_to_files(&nickel_code)?, }) } } ``` --- ## 4. Provisioning: Especificaciones ### Directory Structure ```text provisioning/ ├── core/ │ ├── cli/ # Main CLI (211 lines) │ ├── nulib/ # Nushell libraries (476+ accessors) │ └── scripts/ # Utility scripts ├── extensions/ │ ├── providers/ # AWS, UpCloud, Local │ ├── taskservs/ # 50+ infrastructure services │ ├── clusters/ # Deployment templates │ └── workflows/ # Automation workflows ├── platform/ │ ├── orchestrator/ # Workflow execution (Rust) │ ├── control-center/ # Backend (Axum + RBAC) │ ├── control-center-ui/ # Web dashboard (Leptos) │ ├── installer/ # Multi-mode installer │ ├── mcp-server/ # MCP server (Rust) │ ├── ai-service/ # AI operations │ ├── rag/ # RAG system │ ├── vault-service/ # Secrets management │ └── detector/ # Anomaly detection └── schemas/ # Nickel IaC schemas ``` ### Nickel IaC Schema ```nickel # schemas/server.ncl let Server = { name | String, provider | [ | 'aws, 'upcloud, 'local |], spec | { cpu | Number | default = 2, memory_gb | Number | default = 4, disk_gb | Number | default = 50, os | { family | [ | 'ubuntu, 'debian, 'rocky |], version | String, }, }, networking | { vpc | String | optional, subnet | String | optional, public_ip | Bool | default = false, security_groups | Array String | default = [], }, tags | { _ : String } | default = {}, } in Server ``` ### Orchestrator API ```rust // platform/orchestrator/src/lib.rs pub struct Orchestrator { state: StateManager, executor: WorkflowExecutor, scheduler: Scheduler, } impl Orchestrator { pub async fn execute_workflow(&self, workflow: Workflow) -> Result<ExecutionResult> { // 1. Resolve dependencies (topological sort) let ordered_tasks = self.resolve_dependencies(&workflow)?; // 2. Create execution checkpoints let checkpoint = self.state.create_checkpoint(&workflow)?; // 3. Execute tasks with retry logic for task in ordered_tasks { match self.executor.run(&task).await { Ok(result) => { self.state.record_success(&task, &result)?; } Err(e) => { // Exponential backoff retry if let Some(result) = self.retry_with_backoff(&task).await? { self.state.record_success(&task, &result)?; } else { // Rollback to checkpoint self.state.rollback(&checkpoint)?; return Err(e); } } } } Ok(ExecutionResult::from_state(&self.state)) } } ``` ### MCP Tools ```rust // platform/mcp-server/src/tools.rs pub const MCP_TOOLS: &[Tool] = &[ Tool { name: "query_infrastructure", description: "Query infrastructure state using natural language", parameters: json!({ "query": { "type": "string" }, "provider": { "type": "string", "optional": true } }), }, Tool { name: "generate_config", description: "Generate Nickel configuration from description", parameters: json!({ "description": { "type": "string" }, "provider": { "type": "string" }, "resource_type": { "type": "string" } }), }, Tool { name: "validate_config", description: "Validate Nickel configuration", parameters: json!({ "config": { "type": "string" }, "strict": { "type": "boolean", "default": true } }), }, Tool { name: "estimate_cost", description: "Estimate monthly cost for configuration", parameters: json!({ "config": { "type": "string" }, "region": { "type": "string", "optional": true } }), }, Tool { name: "check_compliance", description: "Check configuration against compliance rules", parameters: json!({ "config": { "type": "string" }, "framework": { "type": "string", "enum": ["soc2", "hipaa", "gdpr", "pci"] } }), }, Tool { name: "plan_migration", description: "Generate migration plan between configurations", parameters: json!({ "current": { "type": "string" }, "target": { "type": "string" } }), }, Tool { name: "execute_workflow", description: "Execute provisioning workflow", parameters: json!({ "workflow_id": { "type": "string" }, "dry_run": { "type": "boolean", "default": true } }), }, ]; ``` ### RAG Configuration ```rust // platform/rag/src/config.rs pub struct RagConfig { pub embedding_model: String, // "text-embedding-3-small" pub embedding_dimensions: usize, // 1536 pub chunk_size: usize, // 512 tokens pub chunk_overlap: usize, // 50 tokens pub top_k: usize, // 5 results pub min_similarity: f32, // 0.7 pub reranker: Option<RerankerConfig>, } pub struct RagService { embedder: Box<dyn Embedder>, vector_store: Box<dyn VectorStore>, keyword_index: tantivy::Index, } impl RagService { pub async fn query(&self, question: &str) -> Result<Vec<Document>> { // 1. Generate embedding for question let embedding = self.embedder.embed(question).await?; // 2. Vector similarity search let vector_results = self.vector_store.search(&embedding, self.config.top_k).await?; // 3. BM25 keyword search let keyword_results = self.keyword_search(question)?; // 4. Hybrid ranking (RRF) let merged = self.reciprocal_rank_fusion(vector_results, keyword_results); // 5. Optional reranking if let Some(reranker) = &self.reranker { return reranker.rerank(&merged, question).await; } Ok(merged) } } ``` --- ## 5. SecretumVault: Especificaciones ### Arquitectura General ```text ┌─────────────────────────────────────────────────────────────────┐ │ SecretumVault (~11K LOC, 50+ tests) │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │ │ │ CLI │ │ REST API │ │ Secrets Engines │ │ │ │ (clap) │ │ (Axum) │ │ KV/Transit/PKI/DB │ │ │ └──────┬──────┘ └──────┬──────┘ └────────────┬────────────┘ │ │ │ │ │ │ │ ┌──────┴────────────────┴──────────────────────┴─────────────┐ │ │ │ VaultCore │ │ │ │ Seal (Shamir) │ TokenManager │ Cedar ABAC │ Metrics │ │ │ └────────────────────────────────────────────────────────────┘ │ │ │ │ │ ┌───────────────────────┴───────────────────────────────────┐ │ │ │ Crypto Backends │ │ │ │ OpenSSL │ OQS (PQC) │ AWS-LC │ RustCrypto │ │ │ └───────────────────────────────────────────────────────────┘ │ │ │ │ │ ┌───────────────────────┴───────────────────────────────────┐ │ │ │ Storage Backends │ │ │ │ Filesystem │ etcd │ SurrealDB │ PostgreSQL │ │ │ └───────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ ``` ### Core Types ```rust // src/core/vault.rs pub struct VaultCore { pub engines: HashMap<String, Box<dyn Engine>>, pub storage: Arc<dyn StorageBackend>, pub crypto: Arc<dyn CryptoBackend>, pub seal: Arc<tokio::sync::Mutex<SealMechanism>>, pub token_manager: Arc<TokenManager>, pub metrics: Arc<Metrics>, } // src/crypto/mod.rs #[async_trait] pub trait CryptoBackend: Send + Sync { async fn generate_keypair(&self, algorithm: KeyAlgorithm) -> CryptoResult<KeyPair>; async fn sign(&self, key: &PrivateKey, data: &[u8]) -> CryptoResult<Vec<u8>>; async fn verify(&self, key: &PublicKey, data: &[u8], sig: &[u8]) -> CryptoResult<bool>; async fn encrypt(&self, plaintext: &[u8]) -> CryptoResult<Vec<u8>>; async fn decrypt(&self, ciphertext: &[u8]) -> CryptoResult<Vec<u8>>; // Post-Quantum (OQS backend) async fn kem_encapsulate(&self, public_key: &[u8]) -> CryptoResult<KemResult>; async fn kem_decapsulate(&self, ciphertext: &[u8]) -> CryptoResult<Vec<u8>>; } // src/storage/mod.rs #[async_trait] pub trait StorageBackend: Send + Sync { async fn store_secret(&self, path: &str, data: &EncryptedData) -> StorageResult<()>; async fn get_secret(&self, path: &str) -> StorageResult<EncryptedData>; async fn delete_secret(&self, path: &str) -> StorageResult<()>; async fn list_secrets(&self, prefix: &str) -> StorageResult<Vec<String>>; } ``` ### Crypto Backends ```rust // src/crypto/backends/ pub enum CryptoBackendType { OpenSSL, // RSA, ECDSA, AES-256-GCM Oqs, // ML-KEM-768, ML-DSA-65 (NIST FIPS 203/204) AwsLc, // RSA, ECDSA (experimental PQC) RustCrypto, // AES-GCM, ChaCha20-Poly1305 (testing) } // OQS Post-Quantum (production-ready) pub struct OqsBackend { kem_algorithm: oqs::kem::Algorithm, // MlKem768 sig_algorithm: oqs::sig::Algorithm, // MlDsa65 } impl OqsBackend { pub async fn kem_keygen(&self) -> CryptoResult<KemKeyPair> { // ML-KEM-768: 1088 bytes ciphertext, 32 bytes shared secret let kem = oqs::kem::Kem::new(self.kem_algorithm)?; let (pk, sk) = kem.keypair()?; Ok(KemKeyPair { public_key: pk, secret_key: sk }) } pub async fn sign(&self, sk: &[u8], message: &[u8]) -> CryptoResult<Vec<u8>> { // ML-DSA-65 signatures let sig = oqs::sig::Sig::new(self.sig_algorithm)?; let signature = sig.sign(message, sk)?; Ok(signature.into_vec()) } } ``` ### Secrets Engines ```rust // src/engines/mod.rs pub trait Engine: Send + Sync { fn name(&self) -> &str; fn engine_type(&self) -> &str; async fn read(&self, path: &str) -> Result<Option<Value>>; async fn write(&self, path: &str, data: &Value) -> Result<()>; async fn delete(&self, path: &str) -> Result<()>; async fn list(&self, prefix: &str) -> Result<Vec<String>>; } // Engines disponibles pub struct KvEngine { /* Versioned secret storage */ } pub struct TransitEngine { /* Encryption-as-a-service */ } pub struct PkiEngine { /* X.509 certificates */ } pub struct DatabaseEngine { /* Dynamic credentials */ } ``` ### Seal Mechanism (Shamir) ```rust // src/core/seal.rs pub struct SealMechanism { state: SealState, shares: Vec<SecretShare>, threshold: u8, total_shares: u8, } pub enum SealState { Sealed, Unsealing { collected: usize }, Unsealed { master_key: Vec<u8> }, } impl SealMechanism { pub fn init(&mut self, shares: u8, threshold: u8) -> Result<Vec<SecretShare>> { // Generate master key and split with Shamir let master_key = generate_random_bytes(32)?; let sharks = Sharks(threshold); let dealer = sharks.dealer(&master_key); let shares: Vec<_> = dealer.take(shares as usize).collect(); self.state = SealState::Sealed; Ok(shares) } pub fn unseal(&mut self, share: SecretShare) -> Result<UnsealProgress> { // Collect shares until threshold met self.shares.push(share); if self.shares.len() >= self.threshold as usize { let sharks = Sharks(self.threshold); let master_key = sharks.recover(&self.shares)?; self.state = SealState::Unsealed { master_key }; return Ok(UnsealProgress::Complete); } Ok(UnsealProgress::NeedMore { collected: self.shares.len() }) } } ``` ### Authorization (Cedar ABAC) ```rust // src/auth/cedar.rs pub struct CedarAuthorizer { engine: cedar_policy::Authorizer, policies: cedar_policy::PolicySet, } impl CedarAuthorizer { pub fn authorize(&self, request: &AuthzRequest) -> Result<Decision> { let principal = self.build_principal(&request.user)?; let action = self.build_action(&request.action)?; let resource = self.build_resource(&request.resource)?; let decision = self.engine.is_authorized( &principal, &action, &resource, &self.policies, )?; Ok(decision) } } ``` ### API Endpoints ```rust // src/api/routes.rs Router::new() // System .route("/v1/sys/health", get(health_check)) .route("/v1/sys/init", post(initialize_vault)) .route("/v1/sys/seal", post(seal_vault)) .route("/v1/sys/unseal", post(unseal_vault)) .route("/v1/sys/mounts", get(list_mounts)) // Secrets (dynamic routing by engine) .route("/v1/*path", get(read_secret) .post(write_secret) .delete(delete_secret)) // Metrics .route("/metrics", get(prometheus_metrics)) ``` ### Configuration (TOML) ```toml # svault.toml [vault] crypto_backend = "oqs" # openssl | oqs | aws-lc | rustcrypto [server] address = "0.0.0.0:8200" tls_cert = "/path/to/cert.pem" tls_key = "/path/to/key.pem" [storage] backend = "etcd" # filesystem | etcd | surrealdb | postgresql [storage.etcd] endpoints = ["http://localhost:2379"] [seal.shamir] shares = 5 threshold = 3 [auth] token_ttl = "24h" ``` ### CLI Commands ```bash # Server svault server --config svault.toml # Operator svault operator init --shares 5 --threshold 3 svault operator unseal --share <share> svault operator seal svault operator status # Secrets svault secret read secret/myapp svault secret write secret/myapp key=value svault secret delete secret/myapp svault secret list secret/ ``` ### Feature Flags ```toml # Cargo.toml features [features] default = ["openssl", "filesystem", "server", "pqc"] # Crypto backends openssl = ["dep:openssl"] aws-lc = ["dep:aws-lc-rs"] pqc = ["dep:oqs"] rustcrypto = ["dep:aes-gcm", "dep:chacha20poly1305"] # Storage backends filesystem = [] surrealdb-storage = ["dep:surrealdb"] etcd-storage = ["dep:etcd-client"] postgresql-storage = ["dep:sqlx"] # Components server = ["dep:axum", "dep:rustls"] cli = ["dep:clap"] cedar = ["dep:cedar-policy"] ``` --- ## 6. Integración entre Proyectos ### Diagrama de Dependencias ```text ┌───────────────────┐ │ Kogral │ │ (Knowledge Graph) │ └─────────┬─────────┘ │ MCP (guidelines, patterns, decisions) │ ┌─────────────────────────┼─────────────────────────┐ │ │ │ ▼ ▼ ▼ ┌─────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ Vapora │ │ TypeDialog │ │ Provisioning │ │(Orchestrate)│ │ (Forms/UI) │ │ (IaC) │ └──────┬──────┘ └────────┬────────┘ └────────┬────────┘ │ │ │ │ ┌─────────────┴─────────────┐ │ │ │ │ │ │ ▼ ▼ │ │ ┌───────────────────────────────┐ │ │ │ SecretumVault │ │ │ │ (Secrets + PQC Crypto) │ │ │ └───────────────────────────────┘ │ │ │ │ └──────────────────┼────────────────────┘ │ ┌─────────┴─────────┐ │ SurrealDB │ │ (Shared State) │ └───────────────────┘ ``` ### Shared Dependencies (Cargo.toml) ```toml # Dependencias comunes a todos los proyectos [dependencies] # Runtime tokio = { version = "1.48", features = ["full"] } # Serialization serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" # Database surrealdb = "2.3" # Web axum = "0.8" # LLM rig-core = "0.15" # Config nickel-lang-core = "1.15" # Logging tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] } # Error handling anyhow = "1.0" thiserror = "2.0" ``` ### SurrealDB Schema Compartido ```sql -- Namespace compartido para cross-project state DEFINE NAMESPACE portfolio; -- Scope para cada proyecto DEFINE DATABASE vapora; DEFINE DATABASE kogral; DEFINE DATABASE typedialog; DEFINE DATABASE provisioning; DEFINE DATABASE secretumvault; -- Tabla compartida para execution records DEFINE TABLE executions SCHEMAFULL; DEFINE FIELD project ON executions TYPE string; DEFINE FIELD task_type ON executions TYPE string; DEFINE FIELD agent_id ON executions TYPE string; DEFINE FIELD status ON executions TYPE string; DEFINE FIELD duration_ms ON executions TYPE int; DEFINE FIELD tokens_used ON executions TYPE int; DEFINE FIELD cost_cents ON executions TYPE float; DEFINE FIELD created_at ON executions TYPE datetime DEFAULT time::now(); -- Índices para queries cross-project DEFINE INDEX idx_executions_project ON executions FIELDS project; DEFINE INDEX idx_executions_agent ON executions FIELDS agent_id; ``` ### Ejemplo de Integración: Feature Development ```rust // Flujo integrado de desarrollo de feature async fn develop_feature(feature_spec: &str) -> Result<FeatureResult> { // 1. Kogral: Obtener contexto del proyecto let kogral_client = KogralMcpClient::connect().await?; let guidelines = kogral_client.call("get_guidelines", json!({ "topic": feature_spec, "include_shared": true })).await?; let patterns = kogral_client.call("search", json!({ "query": feature_spec, "node_type": "pattern", "limit": 5 })).await?; // 2. TypeDialog: Capturar configuración adicional let typedialog = TypeDialog::new(BackendType::Cli); let config = typedialog.execute_form("feature_config.toml").await?; // 3. Vapora: Orquestar agentes let vapora_client = VaporaClient::new("http://localhost:8001"); // Crear tarea con contexto let task = vapora_client.create_task(TaskRequest { title: format!("Implement: {}", feature_spec), context: json!({ "guidelines": guidelines, "patterns": patterns, "config": config, }), task_type: "feature_implementation", }).await?; // Ejecutar pipeline let pipeline = vec![ ("architect", "Design feature architecture"), ("developer", "Implement feature"), ("reviewer", "Review implementation"), ("tester", "Write and run tests"), ]; for (role, description) in pipeline { vapora_client.assign_task(&task.id, role, description).await?; vapora_client.wait_for_completion(&task.id).await?; } // 4. Kogral: Registrar decisión kogral_client.call("add_decision", json!({ "title": format!("Feature: {}", feature_spec), "context": &task.context, "decision": &task.result, "consequences": "Implementation completed" })).await?; // 5. Provisioning: Desplegar si es necesario if config.requires_infra { let prov_client = ProvisioningMcpClient::connect().await?; prov_client.call("execute_workflow", json!({ "workflow_id": config.deployment_workflow, "dry_run": false })).await?; } Ok(FeatureResult { task_id: task.id, status: task.status, }) } ``` --- ## 7. Métricas de Calidad | Proyecto | Tests | Cobertura | Clippy | Unsafe | Doc Coverage | | ---------- | ------- | ----------- | -------- | -------- | -------------- | | Vapora | 218 | ~70% | 0 warnings | 0 | 100% public | | Kogral | 56 | ~80% | 0 warnings | 0 | 100% public | | TypeDialog | 3,818 | ~85% | 0 warnings | 0 | 100% public | | Provisioning | 218 | ~65% | 0 warnings | 0 | 100% public | | SecretumVault | 50+ | ~75% | 0 warnings | 0 | 100% public | ### Comandos de Verificación ```bash # Por proyecto cargo clippy --all-targets --all-features -- -D warnings cargo test --workspace cargo doc --no-deps # Coverage (requiere tarpaulin) cargo tarpaulin --workspace --out Html # Benchmarks cargo bench --workspace ``` --- *Documento generado: 2026-01-22* *Tipo: info (especificaciones técnicas)*