stratumiops/docs/es/stratiumiops-technical-specs.md
Jesús Pérez 1680d80a3d
Some checks failed
Rust CI / Security Audit (push) Has been cancelled
Rust CI / Check + Test + Lint (nightly) (push) Has been cancelled
Rust CI / Check + Test + Lint (stable) (push) Has been cancelled
Nickel Type Check / Nickel Type Checking (push) Has been cancelled
chore: Init repo, add docs
2026-01-22 22:15:19 +00:00

62 KiB

Portfolio: Especificaciones Técnicas Completas

Arquitectura del Ecosistema

┌─────────────────────────────────────────────────────────────────────────────────┐
│                              CAPA DE USUARIO                                    │
├─────────────────────────────────────────────────────────────────────────────────┤
│  Leptos WASM     │  Ratatui TUI     │  CLI (clap)     │  MCP Protocol           │
│  (Vapora, Prov)  │  (TypeDialog,    │  (todos)        │  (Kogral, Prov)         │
│                  │   Prov)          │                 │                         │
└─────────────────────────────────────────────────────────────────────────────────┘
                                      │
                                      ▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│                              CAPA DE API                                        │
├─────────────────────────────────────────────────────────────────────────────────┤
│  Axum REST       │  WebSocket       │  JSON-RPC 2.0   │  NATS JetStream         │
│  (40+ endpoints) │  (real-time)     │  (MCP)          │  (messaging)            │
└─────────────────────────────────────────────────────────────────────────────────┘
                                      │
                                      ▼
┌───────────────────────────────────────────────────────────────────────────────────────┐
│                              CAPA DE DOMINIO                                          │
├───────────────────────────────────────────────────────────────────────────────────────┤
│  Project Mgmt    │  Knowledge Graph │  Form Engine    │  IaC Engine     │ Vault       │
│  (Vapora)        │  (Kogral)        │  (TypeDialog)   │  (Provisioning) │ (SecretumV.)│
│                  │                  │                 │                 │             │
│  Agent Coord     │  Embeddings      │  Agent Exec     │  Orchestrator   │ Seal/Unseal │
│  (Vapora)        │  (Kogral)        │  (TypeDialog)   │  (Provisioning) │ (SecretumV.)│
│                  │                  │                 │                 │             │
│  LLM Router      │  MCP Server      │  Prov-gen       │  Security Layer │             │
│  (Vapora)        │  (Kogral)        │  (TypeDialog)   │  (Provisioning) │             │
└───────────────────────────────────────────────────────────────────────────────────────┘
                                      │
                                      ▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│                              CAPA DE PERSISTENCIA                               │
├─────────────────────────────────────────────────────────────────────────────────┤
│  SurrealDB       │  Filesystem      │  NATS JetStream │  etcd           │ PG   │
│  (multi-tenant   │  (git-native     │  (mensajería    │  (SecretumVault │(Vault│
│   scopes)        │   markdown)      │   durable)      │   HA)           │ ent.)│
└─────────────────────────────────────────────────────────────────────────────────┘

1. Vapora: Especificaciones Completas

Workspace (13 crates)

crates/
├── vapora-shared/         # Core: models, errors, types
├── vapora-backend/        # Axum REST API (40+ endpoints, 79 tests)
├── vapora-agents/         # Agent orchestration + learning (67 tests)
├── vapora-llm-router/     # Multi-provider routing + budget (53 tests)
├── vapora-swarm/          # Swarm coordination + metrics (6 tests)
├── vapora-knowledge-graph/# Temporal KG + learning curves (13 tests)
├── vapora-frontend/       # Leptos WASM UI (Kanban)
├── 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

Domain Models

// vapora-shared/src/models.rs

// ─── Project Management ───────────────────────────────────────
pub struct Project {
    pub id: String,
    pub name: String,
    pub description: Option<String>,
    pub scope: String,              // Multi-tenant scope
    pub status: ProjectStatus,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}

pub enum ProjectStatus {
    Active,
    Archived,
    OnHold,
}

pub struct Task {
    pub id: String,
    pub project_id: String,
    pub title: String,
    pub description: Option<String>,
    pub status: TaskStatus,
    pub priority: TaskPriority,
    pub assigned_agent: Option<String>,
    pub tags: Vec<String>,
    pub order: i32,
    pub created_at: DateTime<Utc>,
}

pub enum TaskStatus {
    Todo,
    Doing,
    Review,
    Done,
}

pub enum TaskPriority {
    Low,
    Medium,
    High,
    Critical,
}

// ─── Agent System ─────────────────────────────────────────────
pub struct Agent {
    pub id: String,
    pub role: AgentRole,
    pub status: AgentStatus,
    pub provider: LLMProvider,
    pub current_load: f64,
    pub last_heartbeat: DateTime<Utc>,
}

pub enum AgentRole {
    Architect,
    Developer,
    CodeReviewer,
    Tester,
    Documenter,
    Marketer,
    Presenter,
    DevOps,
    Monitor,
    Security,
    ProjectManager,
    DecisionMaker,
}

pub enum AgentStatus {
    Ready,
    Busy,
    Offline,
    Maintenance,
}

// ─── Learning System ──────────────────────────────────────────
pub struct ExpertiseProfile {
    pub agent_id: String,
    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
    pub last_updated: DateTime<Utc>,
}

// Scoring: 0.3*load + 0.5*expertise + 0.2*confidence

// ─── LLM Router ───────────────────────────────────────────────
pub enum LLMProvider {
    Claude,
    OpenAI,
    Gemini,
    Ollama,
}

pub struct RoutingRule {
    pub pattern: String,            // Regex for task type
    pub provider: LLMProvider,
    pub model: String,
    pub fallback_chain: Vec<LLMProvider>,
}

pub struct BudgetConfig {
    pub role: AgentRole,
    pub monthly_limit_cents: u32,
    pub weekly_limit_cents: Option<u32>,
    pub enforcement: BudgetEnforcement,
}

pub enum BudgetEnforcement {
    Normal,
    NearThreshold,  // 80%+
    Exceeded,       // 100%+
}

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 agent_id: String,
    pub timestamp: DateTime<Utc>,
}

API Endpoints

// vapora-backend/src/api/mod.rs

// ─── Projects ─────────────────────────────────────────────────
GET    /projects                    // List projects (filtered by scope)
POST   /projects                    // Create project
GET    /projects/:id                // Get project details
PUT    /projects/:id                // Update project
DELETE /projects/:id                // Archive project

// ─── Tasks ────────────────────────────────────────────────────
GET    /projects/:id/tasks          // List tasks for project
POST   /tasks                       // Create task
GET    /tasks/:id                   // Get task details
PUT    /tasks/:id                   // Update task
DELETE /tasks/:id                   // Delete task
POST   /tasks/:id/assign            // Assign to agent
PUT    /tasks/:id/status            // Update status (Kanban)
PUT    /tasks/:id/order             // Reorder task

// ─── Agents ───────────────────────────────────────────────────
GET    /agents                      // List all agents
GET    /agents/:id                  // Get agent details
GET    /agents/:id/health           // Health check
GET    /agents/:role/expertise      // Get expertise for role
POST   /agents/register             // Register new agent
DELETE /agents/:id                  // Unregister agent

// ─── LLM Router ───────────────────────────────────────────────
POST   /llm/route                   // Route request to provider
GET    /llm/providers               // List available providers
GET    /llm/budget/:role            // Get budget status
PUT    /llm/budget/:role            // Set budget limits
GET    /llm/costs                   // Cost report
GET    /llm/costs/:role             // Cost by role
GET    /llm/costs/:provider         // Cost by provider

// ─── Swarm ────────────────────────────────────────────────────
POST   /swarm/assign                // Assign task to swarm
GET    /swarm/status                // Swarm status
GET    /swarm/agents                // List swarm agents
POST   /swarm/balance               // Rebalance load

// ─── Pipelines ────────────────────────────────────────────────
POST   /pipelines                   // Create pipeline
GET    /pipelines/:id               // Get pipeline status
POST   /pipelines/:id/approve       // Approve gate
POST   /pipelines/:id/cancel        // Cancel pipeline

// ─── Knowledge Graph ──────────────────────────────────────────
POST   /knowledge/query             // Query knowledge graph
GET    /knowledge/similar/:task_id  // Find similar past tasks
GET    /knowledge/learning/:agent   // Get learning curve

// ─── Observability ────────────────────────────────────────────
GET    /metrics                     // Prometheus metrics
GET    /health                      // Health check
GET    /health/ready                // Readiness probe
GET    /health/live                 // Liveness probe

NATS Subjects

// vapora-agents/src/messages.rs

// ─── Task Assignment ──────────────────────────────────────────
const TASK_ASSIGN: &str = "vapora.tasks.assign";
// Payload: TaskAssignment { task_id, agent_id, task_type, payload }

const TASK_RESULT: &str = "vapora.tasks.results";
// Payload: TaskResult { task_id, agent_id, status, output, duration_ms, tokens }

// ─── Agent Coordination ───────────────────────────────────────
const AGENT_HEARTBEAT: &str = "vapora.agents.heartbeat";
// Payload: Heartbeat { agent_id, status, current_load }

const AGENT_REGISTER: &str = "vapora.agents.register";
// Payload: AgentRegistration { agent_id, role, capabilities }

// ─── Pipeline Events ──────────────────────────────────────────
const PIPELINE_STAGE: &str = "vapora.pipelines.stage";
// Payload: StageEvent { pipeline_id, stage, status }

const PIPELINE_APPROVAL: &str = "vapora.pipelines.approval";
// Payload: ApprovalRequest { pipeline_id, stage, requester }

Frontend Components (Leptos)

// vapora-frontend/src/components/

// ─── Kanban Board ─────────────────────────────────────────────
#[component]
pub fn KanbanBoard(project_id: String) -> impl IntoView {
    // Columns: Todo, Doing, Review, Done
    // Drag-and-drop with optimistic updates
    // WebSocket subscription for real-time sync
}

#[component]
pub fn KanbanColumn(status: TaskStatus, tasks: Vec<Task>) -> impl IntoView {
    // Droppable zone
    // Task cards with priority indicators
}

#[component]
pub fn TaskCard(task: Task) -> impl IntoView {
    // Draggable card
    // Tags, priority, assignee display
    // Click to open details
}

// ─── Project Management ───────────────────────────────────────
#[component]
pub fn ProjectList() -> impl IntoView {
    // Grid/list view toggle
    // Filter by status
    // Create project modal
}

#[component]
pub fn ProjectDetail(project_id: String) -> impl IntoView {
    // Project info
    // Kanban board
    // Agent assignments
    // Pipeline status
}

// ─── Agent Dashboard ──────────────────────────────────────────
#[component]
pub fn AgentOverview() -> impl IntoView {
    // Agent status grid
    // Load indicators
    // Expertise heatmap
}

#[component]
pub fn CostDashboard() -> impl IntoView {
    // Budget usage by role
    // Cost trends charts
    // Provider breakdown
}

2. Kogral: Especificaciones Completas

Workspace (3 crates)

crates/
├── kogral-core/           # Core library (48 tests)
│   ├── models/           # Node, Edge, Graph types
│   ├── storage/          # Multi-backend storage
│   ├── parser/           # Markdown + YAML parser
│   ├── block_parser/     # Logseq block support
│   ├── query/            # Text + semantic search
│   ├── embeddings/       # fastembed + rig-core
│   ├── export/           # Tera templates
│   ├── sync/             # Filesystem ↔ SurrealDB
│   ├── config/           # Nickel config loader
│   └── inheritance/      # Guideline inheritance
├── kogral-cli/            # CLI (13 commands)
└── kogral-mcp/            # MCP server (7 tools)

Domain Models

// kogral-core/src/models.rs

// ─── Node Types ───────────────────────────────────────────────
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum NodeType {
    Note,           // General notes
    Decision,       // ADRs
    Guideline,      // Standards
    Pattern,        // Reusable solutions
    Journal,        // Daily logs
    Execution,      // Agent records
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Node {
    pub id: String,
    pub node_type: NodeType,
    pub title: String,
    pub content: String,              // Markdown body
    pub metadata: HashMap<String, Value>,
    pub tags: Vec<String>,
    pub graph_id: String,             // Which graph this belongs to
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}

// ─── Relationships ────────────────────────────────────────────
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum RelationType {
    RelatesTo,
    DependsOn,
    Implements,
    Extends,
    Supersedes,
    Explains,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Edge {
    pub source: String,
    pub target: String,
    pub relation: RelationType,
    pub weight: f64,
    pub metadata: HashMap<String, Value>,
}

// ─── Graph ────────────────────────────────────────────────────
#[derive(Debug, Clone)]
pub struct Graph {
    pub id: String,
    pub name: String,
    pub graph_type: GraphType,
    pub nodes: HashMap<String, Node>,
    pub edges: Vec<Edge>,
}

pub enum GraphType {
    Project,        // Local, in .kogral/
    Shared,         // Organization-wide, in SurrealDB
}

// ─── ADR Structure ────────────────────────────────────────────
#[derive(Debug, Serialize, Deserialize)]
pub struct DecisionRecord {
    pub title: String,
    pub status: DecisionStatus,
    pub context: String,
    pub decision: String,
    pub consequences: String,
    pub alternatives: Vec<Alternative>,
    pub related_decisions: Vec<String>,
}

pub enum DecisionStatus {
    Proposed,
    Accepted,
    Deprecated,
    Superseded,
}

// ─── Logseq Blocks ────────────────────────────────────────────
#[derive(Debug, Clone)]
pub struct Block {
    pub id: String,
    pub content: String,
    pub children: Vec<Block>,
    pub properties: HashMap<String, String>,
    pub task_status: Option<TaskStatus>,
    pub tags: Vec<String>,
    pub references: Vec<String>,      // [[wikilinks]]
}

pub enum TaskStatus {
    TODO,
    DOING,
    DONE,
    LATER,
    NOW,
    WAITING,
    CANCELLED,
}

Storage Trait

// kogral-core/src/storage/mod.rs

#[async_trait]
pub trait Storage: Send + Sync {
    // ─── Node Operations ──────────────────────────────────────
    async fn create_node(&self, node: &Node) -> Result<String>;
    async fn get_node(&self, id: &str) -> Result<Option<Node>>;
    async fn update_node(&self, node: &Node) -> Result<()>;
    async fn delete_node(&self, id: &str) -> Result<()>;
    async fn list_nodes(&self, filter: NodeFilter) -> Result<Vec<Node>>;

    // ─── Edge Operations ──────────────────────────────────────
    async fn create_edge(&self, edge: &Edge) -> Result<()>;
    async fn get_edges(&self, node_id: &str, direction: EdgeDirection) -> Result<Vec<Edge>>;
    async fn delete_edge(&self, source: &str, target: &str) -> Result<()>;

    // ─── Search ───────────────────────────────────────────────
    async fn search_text(&self, query: &str, limit: usize) -> Result<Vec<Node>>;
    async fn search_semantic(&self, embedding: &[f32], limit: usize) -> Result<Vec<Node>>;

    // ─── Graph Operations ─────────────────────────────────────
    async fn get_connected(&self, node_id: &str, depth: usize) -> Result<Graph>;
    async fn get_path(&self, from: &str, to: &str) -> Result<Option<Vec<Edge>>>;
}

// Implementations
pub struct FilesystemStorage {
    base_path: PathBuf,  // .kogral/
}

pub struct SurrealDbStorage {
    client: Surreal<Client>,
    namespace: String,
    database: String,
}

pub struct MemoryStorage {
    nodes: DashMap<String, Node>,
    edges: DashMap<String, Vec<Edge>>,
}

Embeddings

// kogral-core/src/embeddings.rs

pub enum EmbeddingProvider {
    FastEmbed {
        model: String,          // "BAAI/bge-small-en-v1.5"
        cache_dir: PathBuf,
    },
    RigCore {
        provider: RigProvider,  // OpenAI, Anthropic, etc.
        model: String,
    },
}

#[async_trait]
pub trait Embedder: Send + Sync {
    async fn embed(&self, text: &str) -> Result<Vec<f32>>;
    async fn embed_batch(&self, texts: &[String]) -> Result<Vec<Vec<f32>>>;
    fn dimensions(&self) -> usize;
    fn model_name(&self) -> &str;
}

// FastEmbed: 384 dimensions, local, offline
pub struct FastEmbedder {
    model: fastembed::TextEmbedding,
}

// RigCore: Cloud providers
pub struct RigEmbedder {
    client: Box<dyn rig_core::Embedder>,
}

CLI Commands

# ─── Initialization ────────────────────────────────────────────
kogral init                          # Create .kogral/ directory
kogral init --with-surreal           # Also setup SurrealDB connection

# ─── Adding Content ────────────────────────────────────────────
kogral add note "Title"              # Interactive note creation
kogral add decision "Title"          # Guided ADR creation
kogral add guideline "Title"         # Add team guideline
kogral add pattern "Title"           # Document pattern
kogral add journal                   # Today's journal entry

# ─── Querying ──────────────────────────────────────────────────
kogral search "query"                # Text search
kogral search --semantic "query"     # Semantic search
kogral search --type decision        # Filter by type
kogral search --tag auth             # Filter by tag

# ─── Relationships ─────────────────────────────────────────────
kogral link <src> <dst> relates_to   # Create relationship
kogral link <src> <dst> implements   # Implementation link
kogral unlink <src> <dst>            # Remove relationship

# ─── Viewing ───────────────────────────────────────────────────
kogral list                          # List all nodes
kogral list --type pattern           # Filter by type
kogral show <id>                     # Display node details
kogral graph                         # Output DOT format
kogral graph --connected <id>        # Subgraph from node

# ─── Sync & Export ─────────────────────────────────────────────
kogral sync                          # Sync filesystem ↔ SurrealDB
kogral export markdown               # Export to markdown
kogral export json                   # Export to JSON
kogral import <path>                 # Import from Logseq/markdown

# ─── MCP Server ────────────────────────────────────────────────
kogral serve                         # Start MCP server (stdio)
kogral serve --port 3000             # HTTP mode

# ─── Configuration ─────────────────────────────────────────────
kogral config                        # Show current config
kogral config set <key> <value>      # Set config value

MCP Protocol

// kogral-mcp/src/protocol.rs

// ─── Tools ────────────────────────────────────────────────────
pub const TOOLS: &[Tool] = &[
    Tool {
        name: "search",
        description: "Search knowledge graph",
        input_schema: json!({
            "type": "object",
            "properties": {
                "query": { "type": "string" },
                "node_type": { "type": "string", "optional": true },
                "semantic": { "type": "boolean", "default": false },
                "limit": { "type": "integer", "default": 10 }
            },
            "required": ["query"]
        }),
    },
    Tool {
        name: "add_note",
        description: "Add a note to the knowledge graph",
        input_schema: json!({...}),
    },
    Tool {
        name: "add_decision",
        description: "Record an architectural decision",
        input_schema: json!({...}),
    },
    Tool {
        name: "link",
        description: "Create relationship between nodes",
        input_schema: json!({...}),
    },
    Tool {
        name: "get_guidelines",
        description: "Get applicable guidelines",
        input_schema: json!({...}),
    },
    Tool {
        name: "list_graphs",
        description: "List available knowledge graphs",
        input_schema: json!({}),
    },
    Tool {
        name: "export",
        description: "Export knowledge graph",
        input_schema: json!({...}),
    },
];

// ─── Resources ────────────────────────────────────────────────
pub const RESOURCES: &[Resource] = &[
    Resource {
        uri: "kogral://project/notes",
        name: "Project Notes",
        description: "All notes in current project",
    },
    Resource {
        uri: "kogral://project/decisions",
        name: "Project Decisions",
        description: "All ADRs in current project",
    },
    Resource {
        uri: "kogral://project/guidelines",
        name: "Project Guidelines",
        description: "Effective guidelines (with inheritance)",
    },
    Resource {
        uri: "kogral://project/patterns",
        name: "Project Patterns",
        description: "All patterns in current project",
    },
    Resource {
        uri: "kogral://shared/guidelines",
        name: "Shared Guidelines",
        description: "Organization-wide guidelines",
    },
    Resource {
        uri: "kogral://shared/patterns",
        name: "Shared Patterns",
        description: "Organization-wide patterns",
    },
];

// ─── Prompts ──────────────────────────────────────────────────
pub const PROMPTS: &[Prompt] = &[
    Prompt {
        name: "summarize_project",
        description: "Summarize project knowledge",
        arguments: json!([]),
    },
    Prompt {
        name: "find_related",
        description: "Find related knowledge for a topic",
        arguments: json!([
            { "name": "topic", "required": true }
        ]),
    },
];

3. TypeDialog: Especificaciones Completas

Workspace (8 crates)

crates/
├── typedialog-core/               # Core library
│   ├── form/                     # Form models
│   ├── field/                    # Field types (8)
│   ├── validation/               # Validators
│   ├── backend/                  # Backend trait
│   ├── backends/                 # 6 implementations
│   ├── output/                   # 4 output formats
│   ├── i18n/                     # Fluent integration
│   └── nickel/                   # Contract validation
├── typedialog/                    # CLI binary
├── typedialog-tui/                # TUI binary
├── typedialog-web/                # Web binary
├── typedialog-ai/                 # AI backend
├── typedialog-agent/
│   ├── typedialog-ag-core/       # Agent runtime
│   └── typedialog-ag/            # Agent CLI
└── typedialog-prov-gen/           # IaC generation

Form Schema

# Form definition (TOML)

[form]
id = "example_form"
version = "1.0.0"
title = "Example Form"
description = "Demonstrates all features"

# ─── Sections ──────────────────────────────────────────────────
[[sections]]
id = "basic"
title = "Basic Information"
description = "Required fields"

[[sections.fields]]
id = "name"
type = "text"
label = "Full Name"
required = true
validation.min_length = 2
validation.max_length = 100
validation.pattern = "^[a-zA-Z\\s]+$"

[[sections.fields]]
id = "email"
type = "text"
label = "Email Address"
required = true
validation.pattern = "^[^@]+@[^@]+\\.[^@]+$"

[[sections.fields]]
id = "department"
type = "select"
label = "Department"
required = true
options = [
    { value = "engineering", label = "Engineering" },
    { value = "product", label = "Product" },
    { value = "design", label = "Design" },
]

# ─── Conditional Fields ────────────────────────────────────────
[[sections.fields]]
id = "team_size"
type = "select"
label = "Team Size"
condition = { field = "department", equals = "engineering" }
options = [
    { value = "small", label = "1-5" },
    { value = "medium", label = "6-20" },
    { value = "large", label = "20+" },
]

# ─── Multi-select ──────────────────────────────────────────────
[[sections.fields]]
id = "skills"
type = "multi-select"
label = "Skills"
display_mode = "grid"  # list, grid, dropdown
options = [
    { value = "rust", label = "Rust" },
    { value = "typescript", label = "TypeScript" },
    { value = "python", label = "Python" },
    { value = "go", label = "Go" },
]

# ─── Repeating Groups ──────────────────────────────────────────
[[sections.fields]]
id = "projects"
type = "group"
label = "Previous Projects"
repeatable = true
min_items = 1
max_items = 5

[[sections.fields.fields]]
id = "project_name"
type = "text"
label = "Project Name"

[[sections.fields.fields]]
id = "project_role"
type = "select"
label = "Role"
options = [...]

# ─── Output ────────────────────────────────────────────────────
[output]
format = "json"                    # json, yaml, toml, nickel
validation = "nickel://schemas/employee.ncl"
template = "templates/output.tera"

Backend Trait

// typedialog-core/src/backend/mod.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
    }

    fn supports_validation(&self) -> bool {
        true
    }
}

// ─── Backend Factory ──────────────────────────────────────────
pub enum BackendType {
    Cli,
    Tui,
    Web,
    Ai,
    Agent,
    ProvGen,
}

pub struct BackendFactory;

impl BackendFactory {
    pub fn create(backend_type: BackendType, config: &Config) -> Box<dyn Backend> {
        match backend_type {
            BackendType::Cli => Box::new(CliBackend::new(config)),
            BackendType::Tui => Box::new(TuiBackend::new(config)),
            BackendType::Web => Box::new(WebBackend::new(config)),
            BackendType::Ai => Box::new(AiBackend::new(config)),
            BackendType::Agent => Box::new(AgentBackend::new(config)),
            BackendType::ProvGen => Box::new(ProvGenBackend::new(config)),
        }
    }
}

// ─── CLI Backend ──────────────────────────────────────────────
pub struct CliBackend {
    theme: inquire::ui::RenderConfig,
}

// ─── TUI Backend ──────────────────────────────────────────────
pub struct TuiBackend {
    terminal: Terminal<CrosstermBackend<Stdout>>,
}

// ─── Web Backend ──────────────────────────────────────────────
pub struct WebBackend {
    port: u16,
    templates: tera::Tera,
}

// ─── AI Backend ───────────────────────────────────────────────
pub struct AiBackend {
    index: tantivy::Index,
    embedder: Box<dyn Embedder>,
    graph: petgraph::Graph<String, String>,
}

// ─── Agent Backend ────────────────────────────────────────────
pub struct AgentBackend {
    providers: HashMap<String, Box<dyn LLMProvider>>,
    templates: tera::Tera,
}

// ─── ProvGen Backend ──────────────────────────────────────────
pub struct ProvGenBackend {
    templates: HashMap<CloudProvider, tera::Tera>,
    validators: Vec<Box<dyn Validator>>,
}

Agent MDX Format

---
name: code_reviewer
version: "1.0"
provider: claude
model: claude-sonnet-4-20250514
temperature: 0.3
max_tokens: 4096
output_format: json
output_schema: |
  {
    "type": "object",
    "properties": {
      "issues": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "severity": { "enum": ["critical", "warning", "info"] },
            "line": { "type": "integer" },
            "message": { "type": "string" },
            "suggestion": { "type": "string" }
          }
        }
      },
      "summary": { "type": "string" }
    }
  }
---

# Code Review Agent

## System

You are an expert code reviewer...

## User

Review this {{language}} code:

```{{language}}
{{code}}

Guidelines: {{guidelines}}


### IaC Generation

```rust
// typedialog-prov-gen/src/lib.rs

pub enum CloudProvider {
    Aws,
    Gcp,
    Azure,
    Hetzner,
    UpCloud,
    Lxd,
}

pub struct InfraConfig {
    pub provider: CloudProvider,
    pub region: String,
    pub environment: Environment,
    pub resources: Vec<Resource>,
    pub networking: NetworkConfig,
    pub security: SecurityConfig,
    pub tags: HashMap<String, String>,
}

pub struct Generator {
    templates: HashMap<CloudProvider, tera::Tera>,
    validators: ValidationPipeline,  // 7 layers
}

impl Generator {
    pub async fn generate(&self, config: &InfraConfig) -> Result<GeneratedIaC> {
        // 1. Input validation
        self.validators.validate_input(config)?;

        // 2. Load provider template
        let template = self.templates
            .get(&config.provider)
            .ok_or(Error::UnsupportedProvider)?;

        // 3. Render Nickel
        let nickel = template.render("main.ncl.tera", &config)?;

        // 4. Validate generated Nickel
        self.validators.validate_nickel(&nickel)?;

        // 5. Split into files
        let files = self.split_output(&nickel, config)?;

        Ok(GeneratedIaC { provider: config.provider, files })
    }
}

// 7-Layer Validation Pipeline
pub struct ValidationPipeline {
    layers: Vec<Box<dyn Validator>>,
}

// Layers:
// 1. Schema validation (structure)
// 2. Type validation (Nickel contracts)
// 3. Provider validation (provider-specific rules)
// 4. Security validation (no exposed secrets)
// 5. Cost validation (budget limits)
// 6. Compliance validation (policy rules)
// 7. Integration validation (cross-resource refs)

4. Provisioning: Especificaciones Completas

Directory Structure

provisioning/
├── core/
│   ├── cli/                       # Main CLI (211 lines)
│   ├── nulib/                     # Nushell libraries
│   │   ├── config.nu             # 476+ accessors
│   │   ├── provider.nu           # Provider abstraction
│   │   ├── workflow.nu           # Workflow execution
│   │   └── utils.nu              # Utilities
│   └── scripts/                   # Automation scripts
├── extensions/
│   ├── providers/
│   │   ├── aws/                  # AWS provider
│   │   ├── upcloud/              # UpCloud provider
│   │   └── local/                # Local (LXD) provider
│   ├── taskservs/                 # 50+ services
│   ├── clusters/                  # Deployment templates
│   └── workflows/                 # Workflow definitions
├── platform/
│   ├── orchestrator/              # Rust workflow engine
│   ├── control-center/            # Axum backend
│   ├── control-center-ui/         # Leptos frontend
│   ├── installer/                 # Multi-mode installer
│   ├── mcp-server/                # MCP server
│   ├── ai-service/                # AI operations
│   ├── rag/                       # RAG system
│   ├── vault-service/             # Secrets management
│   ├── detector/                  # Anomaly detection
│   ├── extension-registry/        # Extension catalog
│   └── provisioning-daemon/       # Service daemon
├── schemas/                       # Nickel schemas
│   ├── server.ncl
│   ├── network.ncl
│   ├── storage.ncl
│   ├── kubernetes.ncl
│   └── security.ncl
└── docs/                          # Documentation

Nickel Schemas

# schemas/server.ncl

let Server = {
  name
    | String
    | doc "Server hostname",

  provider
    | [ | 'aws, 'upcloud, 'local |]
    | doc "Cloud provider",

  spec
    | {
        cpu
          | Number
          | default = 2
          | doc "CPU cores",
        memory_gb
          | Number
          | default = 4
          | doc "Memory in GB",
        disk_gb
          | Number
          | default = 50
          | doc "Root disk in GB",
        os
          | {
              family | [ |  'ubuntu, 'debian, 'rocky |],
              version | String,
            },
      },

  networking
    | {
        vpc | String | optional,
        subnet | String | optional,
        public_ip | Bool | default = false,
        security_groups | Array String | default = [],
        private_ip | String | optional,
      },

  storage
    | Array {
        name | String,
        size_gb | Number,
        type | [ |  'ssd, 'hdd, 'nvme |] | default = 'ssd,
        mount_point | String,
      }
    | default = [],

  tags
    | { _ : String }
    | default = {},

  metadata
    | { _ : Dyn }
    | default = {},
}
in Server

Orchestrator

// platform/orchestrator/src/lib.rs

pub struct Orchestrator {
    state: StateManager,
    executor: WorkflowExecutor,
    scheduler: Scheduler,
    providers: HashMap<String, Box<dyn Provider>>,
}

impl Orchestrator {
    pub async fn execute(&self, workflow: Workflow) -> Result<ExecutionResult> {
        // 1. Create checkpoint
        let checkpoint = self.state.checkpoint(&workflow)?;

        // 2. Resolve dependencies (topological sort)
        let tasks = self.resolve_dependencies(&workflow)?;

        // 3. Execute with retry
        for task in tasks {
            let result = self.execute_with_retry(&task).await;

            match result {
                Ok(output) => {
                    self.state.record_success(&task, &output)?;
                }
                Err(e) => {
                    // Rollback to checkpoint
                    self.state.rollback(&checkpoint)?;
                    return Err(e);
                }
            }
        }

        Ok(ExecutionResult::success())
    }

    async fn execute_with_retry(&self, task: &Task) -> Result<Output> {
        let mut attempts = 0;
        let max_attempts = task.retry_config.max_attempts;

        loop {
            attempts += 1;
            match self.executor.run(task).await {
                Ok(output) => return Ok(output),
                Err(e) if attempts < max_attempts => {
                    let delay = self.calculate_backoff(attempts);
                    tokio::time::sleep(delay).await;
                }
                Err(e) => return Err(e),
            }
        }
    }

    fn calculate_backoff(&self, attempt: u32) -> Duration {
        // Exponential backoff: 2^attempt * base_delay
        Duration::from_secs(2u64.pow(attempt) * self.config.base_delay_secs)
    }
}

// ─── State Management ─────────────────────────────────────────
pub struct StateManager {
    store: Box<dyn StateStore>,
}

impl StateManager {
    pub fn checkpoint(&self, workflow: &Workflow) -> Result<Checkpoint> {
        let state = self.capture_current_state(workflow)?;
        let id = self.store.save_checkpoint(&state)?;
        Ok(Checkpoint { id, state })
    }

    pub fn rollback(&self, checkpoint: &Checkpoint) -> Result<()> {
        self.restore_state(&checkpoint.state)
    }
}

Security Layer

// platform/control-center/src/security/

// ─── Authentication ───────────────────────────────────────────
pub struct AuthService {
    jwt_secret: Secret<String>,
    hasher: Argon2Config,
    mfa: MfaService,
}

impl AuthService {
    pub async fn authenticate(&self, credentials: Credentials) -> Result<Token> {
        // 1. Verify password
        let user = self.verify_password(&credentials)?;

        // 2. Check MFA if enabled
        if user.mfa_enabled {
            self.mfa.verify(&user, &credentials.mfa_code)?;
        }

        // 3. Generate JWT
        let token = self.generate_jwt(&user)?;

        // 4. Audit log
        self.audit.log_authentication(&user, AuthResult::Success)?;

        Ok(token)
    }
}

// ─── MFA Service ──────────────────────────────────────────────
pub struct MfaService {
    totp: TotpProvider,
    webauthn: WebAuthnProvider,
}

impl MfaService {
    pub fn verify(&self, user: &User, code: &MfaCode) -> Result<()> {
        match &user.mfa_method {
            MfaMethod::Totp => self.totp.verify(&user.totp_secret, code),
            MfaMethod::WebAuthn => self.webauthn.verify(&user.credentials, code),
        }
    }
}

// ─── Authorization (Cedar) ────────────────────────────────────
pub struct AuthzService {
    engine: cedar_policy::Authorizer,
    policies: cedar_policy::PolicySet,
}

impl AuthzService {
    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)
    }
}

// ─── KMS ──────────────────────────────────────────────────────
pub enum KmsBackend {
    RustyVault(RustyVaultClient),
    Age(AgeClient),
    AwsKms(AwsKmsClient),
    HashiVault(VaultClient),
    Cosmian(CosmianClient),
}

pub struct KmsService {
    backend: KmsBackend,
}

impl KmsService {
    pub async fn encrypt(&self, plaintext: &[u8], key_id: &str) -> Result<Vec<u8>> {
        // Envelope encryption
        let dek = self.generate_dek()?;
        let ciphertext = self.encrypt_with_dek(plaintext, &dek)?;
        let encrypted_dek = self.wrap_key(&dek, key_id).await?;

        Ok(self.package(ciphertext, encrypted_dek))
    }

    pub async fn decrypt(&self, blob: &[u8], key_id: &str) -> Result<Vec<u8>> {
        let (ciphertext, encrypted_dek) = self.unpackage(blob)?;
        let dek = self.unwrap_key(&encrypted_dek, key_id).await?;
        self.decrypt_with_dek(&ciphertext, &dek)
    }
}

// ─── Audit ────────────────────────────────────────────────────
pub struct AuditService {
    store: Box<dyn AuditStore>,
    retention_years: u32,  // 7 years
}

impl AuditService {
    pub fn log(&self, event: AuditEvent) -> Result<()> {
        let record = AuditRecord {
            id: Uuid::new_v4(),
            timestamp: Utc::now(),
            event,
            user_id: current_user_id()?,
            ip_address: current_ip()?,
            user_agent: current_user_agent()?,
        };

        self.store.save(&record)
    }

    pub fn export(&self, format: ExportFormat, range: DateRange) -> Result<Vec<u8>> {
        let records = self.store.query(range)?;

        match format {
            ExportFormat::Json => serde_json::to_vec(&records),
            ExportFormat::Csv => self.to_csv(&records),
            ExportFormat::Parquet => self.to_parquet(&records),
            ExportFormat::Avro => self.to_avro(&records),
            ExportFormat::Pdf => self.to_pdf(&records),
        }
    }
}

MCP Server

// platform/mcp-server/src/tools.rs

pub const TOOLS: &[Tool] = &[
    // ─── Query Tools ──────────────────────────────────────────
    Tool {
        name: "query_infrastructure",
        description: "Query infrastructure state using natural language",
        input_schema: json!({
            "query": { "type": "string" },
            "provider": { "type": "string", "optional": true }
        }),
    },

    // ─── Generation Tools ─────────────────────────────────────
    Tool {
        name: "generate_config",
        description: "Generate Nickel configuration from description",
        input_schema: json!({
            "description": { "type": "string" },
            "provider": { "type": "string" },
            "resource_type": { "type": "string" }
        }),
    },

    // ─── Validation Tools ─────────────────────────────────────
    Tool {
        name: "validate_config",
        description: "Validate Nickel configuration",
        input_schema: json!({
            "config": { "type": "string" },
            "strict": { "type": "boolean", "default": true }
        }),
    },

    // ─── Cost Tools ───────────────────────────────────────────
    Tool {
        name: "estimate_cost",
        description: "Estimate monthly cost for configuration",
        input_schema: json!({
            "config": { "type": "string" },
            "region": { "type": "string", "optional": true }
        }),
    },

    // ─── Compliance Tools ─────────────────────────────────────
    Tool {
        name: "check_compliance",
        description: "Check configuration against compliance rules",
        input_schema: json!({
            "config": { "type": "string" },
            "framework": { "enum": ["soc2", "hipaa", "gdpr", "pci"] }
        }),
    },

    // ─── Migration Tools ──────────────────────────────────────
    Tool {
        name: "plan_migration",
        description: "Generate migration plan between configurations",
        input_schema: json!({
            "current": { "type": "string" },
            "target": { "type": "string" }
        }),
    },

    // ─── Execution Tools ──────────────────────────────────────
    Tool {
        name: "execute_workflow",
        description: "Execute provisioning workflow",
        input_schema: json!({
            "workflow_id": { "type": "string" },
            "dry_run": { "type": "boolean", "default": true }
        }),
    },
];

5. SecretumVault: Especificaciones Completas

Arquitectura (~11K LOC, 50+ tests)

┌─────────────────────────────────────────────────────────────────┐
│  SecretumVault                                                  │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────────┐  │
│  │  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

// 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

Backend Algoritmos Estado
OpenSSL RSA-2048/4096, ECDSA (P-256/384/521), AES-256-GCM Producción
OQS ML-KEM-768, ML-DSA-65 (NIST FIPS 203/204) Producción (PQC)
AWS-LC RSA, ECDSA (PQC experimental) ⚠️ Experimental
RustCrypto AES-256-GCM, ChaCha20-Poly1305 ⚠️ Testing

Secrets Engines

// 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 Secret Sharing)

// 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> },
}

API Endpoints

// 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))

CLI Commands

# 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

# Cargo.toml features
[features]
default = ["openssl", "filesystem", "server", "pqc"]

# Crypto backends
openssl = ["dep:openssl"]
aws-lc = ["dep:aws-lc-rs"]
pqc = ["dep:oqs"]

# 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 Cross-Project

SurrealDB Schema Compartido

-- ─── Namespace ────────────────────────────────────────────────
DEFINE NAMESPACE portfolio;

-- ─── Databases ────────────────────────────────────────────────
DEFINE DATABASE vapora;
DEFINE DATABASE kogral;
DEFINE DATABASE typedialog;
DEFINE DATABASE provisioning;
DEFINE DATABASE secretumvault;

-- ─── Shared Tables ────────────────────────────────────────────

-- Execution records (cross-project)
DEFINE TABLE executions SCHEMAFULL;
DEFINE FIELD project ON executions TYPE string;
DEFINE FIELD source ON executions TYPE string;  -- vapora, kogral, etc.
DEFINE FIELD task_type ON executions TYPE string;
DEFINE FIELD agent_id ON executions TYPE option<string>;
DEFINE FIELD status ON executions TYPE string;
DEFINE FIELD duration_ms ON executions TYPE int;
DEFINE FIELD metadata ON executions FLEXIBLE TYPE object;
DEFINE FIELD created_at ON executions TYPE datetime DEFAULT time::now();

DEFINE INDEX idx_executions_project ON executions FIELDS project;
DEFINE INDEX idx_executions_source ON executions FIELDS source;
DEFINE INDEX idx_executions_created ON executions FIELDS created_at;

-- Knowledge references (Kogral → others)
DEFINE TABLE knowledge_refs SCHEMAFULL;
DEFINE FIELD source_project ON knowledge_refs TYPE string;
DEFINE FIELD node_id ON knowledge_refs TYPE string;
DEFINE FIELD target_project ON knowledge_refs TYPE string;
DEFINE FIELD target_id ON knowledge_refs TYPE string;
DEFINE FIELD ref_type ON knowledge_refs TYPE string;  -- guideline, pattern, decision
DEFINE FIELD created_at ON knowledge_refs TYPE datetime DEFAULT time::now();

-- Configuration snapshots (TypeDialog → Provisioning)
DEFINE TABLE config_snapshots SCHEMAFULL;
DEFINE FIELD form_id ON config_snapshots TYPE string;
DEFINE FIELD config_hash ON config_snapshots TYPE string;
DEFINE FIELD output ON config_snapshots FLEXIBLE TYPE object;
DEFINE FIELD target ON config_snapshots TYPE string;  -- provisioning workflow
DEFINE FIELD created_at ON config_snapshots TYPE datetime DEFAULT time::now();

Integration Patterns

// Example: Kogral → Vapora integration

// Vapora agent queries Kogral for guidelines before generating code
async fn get_project_context(task: &Task) -> Result<ProjectContext> {
    let kogral = KogralMcpClient::connect().await?;

    // Get applicable guidelines
    let guidelines = kogral.call("get_guidelines", json!({
        "topic": &task.task_type,
        "include_shared": true,
    })).await?;

    // Get relevant patterns
    let patterns = kogral.call("search", json!({
        "query": &task.description,
        "node_type": "pattern",
        "semantic": true,
        "limit": 5,
    })).await?;

    // Get related decisions
    let decisions = kogral.call("search", json!({
        "query": &task.description,
        "node_type": "decision",
        "limit": 3,
    })).await?;

    Ok(ProjectContext { guidelines, patterns, decisions })
}

// Example: TypeDialog → Provisioning integration

// TypeDialog prov-gen backend generates Nickel for Provisioning
async fn generate_infrastructure(form_response: &FormResponse) -> Result<WorkflowId> {
    // Generate Nickel config from form
    let generator = ProvGenBackend::new();
    let iac = generator.generate(&form_response.into()).await?;

    // Submit to Provisioning
    let provisioning = ProvisioningClient::connect().await?;
    let workflow_id = provisioning.submit_workflow(iac).await?;

    // Record in shared DB
    let db = SurrealClient::connect().await?;
    db.create("config_snapshots", ConfigSnapshot {
        form_id: form_response.form_id.clone(),
        config_hash: hash(&iac),
        output: form_response.values.clone(),
        target: workflow_id.clone(),
    }).await?;

    Ok(workflow_id)
}

// Example: Vapora → Kogral integration

// Record agent execution as Kogral Execution node
async fn record_execution(result: &TaskResult) -> Result<()> {
    let kogral = KogralMcpClient::connect().await?;

    kogral.call("add_execution", json!({
        "task_id": &result.task_id,
        "agent_role": &result.agent_role,
        "status": &result.status,
        "duration_ms": result.duration_ms,
        "tokens_used": result.tokens_used,
        "output_summary": &result.summary,
    })).await?;

    Ok(())
}

7. Métricas y Calidad

Proyecto Crates Tests LOC Clippy Unsafe Doc
Vapora 13 218 ~50K 0 warn 0 100% pub
Kogral 3 56 ~15K 0 warn 0 100% pub
TypeDialog 8 3,818 ~90K 0 warn 0 100% pub
Provisioning 15+ 218 ~40K 0 warn 0 100% pub
SecretumVault 1 50+ ~11K 0 warn 0 100% pub
Total 40+ 4,360+ ~206K 0 0 100%

Verification Commands

# All projects
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test --workspace
cargo doc --workspace --no-deps

# Coverage
cargo tarpaulin --workspace --out Html

# Security audit
cargo audit

# Benchmarks
cargo bench --workspace

Documento generado: 2026-01-22 Tipo: info (especificaciones técnicas completas)