Vapora/docs/adrs/0001-cargo-workspace.md
Jesús Pérez 7110ffeea2
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
chore: extend doc: adr, tutorials, operations, etc
2026-01-12 03:32:47 +00:00

5.8 KiB

ADR-001: Cargo Workspace con 13 Crates Especializados

Status: Accepted | Implemented Date: 2024-11-01 Deciders: VAPORA Architecture Team Technical Story: Determining optimal project structure for multi-agent orchestration platform


Decision

Adoptar un Cargo workspace monorepo con 13 crates especializados en lugar de un monolito único o multi-repositorio.

crates/
├── vapora-shared/           # Core models, types, errors
├── vapora-backend/          # REST API (40+ endpoints)
├── vapora-agents/           # Agent orchestration + learning
├── vapora-llm-router/       # Multi-provider LLM routing
├── 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 abstraction
├── vapora-telemetry/        # OpenTelemetry integration
├── vapora-analytics/        # Event pipeline + usage stats
├── vapora-worktree/         # Git worktree management
└── vapora-doc-lifecycle/    # Documentation management

Rationale

  1. Separation of Concerns: Each crate owns a distinct architectural layer (backend API, agents, routing, knowledge graph, etc.)
  2. Independent Testing: 218+ tests can run in parallel across crates without cross-dependencies
  3. Code Reusability: Common utilities (vapora-shared) used by all crates without circular dependencies
  4. Team Parallelization: Multiple teams can develop on different crates simultaneously
  5. Dependency Clarity: Explicit Cargo.toml dependencies prevent accidental coupling
  6. Version Management: Centralized in root Cargo.toml via workspace dependencies prevents version skew

Alternatives Considered

Monolithic Single Crate

  • All code in /src/ directory
  • Pros: Simpler build, familiar structure
  • Cons: Tight coupling, slow compilation, testing all-or-nothing, hard to parallelize development

Multi-Repository

  • Separate Git repos for each component
  • Pros: Independent CI/CD, clear boundaries
  • Cons: Complex synchronization, dependency management nightmare, monorepo benefits lost (atomic commits)

Workspace Monorepo (CHOSEN)

  • 13 crates in single Git repo
  • Pros: Best of both worlds—clear boundaries + atomic commits + shared workspace config

Trade-offs

Pros:

  • Clear architectural boundaries prevent accidental coupling
  • Parallel compilation and testing (cargo builds independent crates concurrently)
  • 218+ tests distributed across crates, faster feedback
  • Atomic commits across multiple components
  • Single CI/CD pipeline, shared version management
  • Easy debugging: each crate is independently debuggable

Cons:

  • ⚠️ Workspace compilation overhead: must compile all dependencies even if using one crate
  • ⚠️ Slightly steeper learning curve for developers new to workspaces
  • ⚠️ Publishing to crates.io requires publishing each crate individually (not a concern for internal project)

Implementation

Cargo.toml Workspace Configuration:

[workspace]
resolver = "2"

members = [
    "crates/vapora-backend",
    "crates/vapora-frontend",
    "crates/vapora-shared",
    "crates/vapora-agents",
    "crates/vapora-llm-router",
    "crates/vapora-mcp-server",
    "crates/vapora-tracking",
    "crates/vapora-worktree",
    "crates/vapora-knowledge-graph",
    "crates/vapora-analytics",
    "crates/vapora-swarm",
    "crates/vapora-telemetry",
]

[workspace.package]
version = "1.2.0"
edition = "2021"
rust-version = "1.75"

Shared Dependencies (defined once, inherited by all crates):

[workspace.dependencies]
tokio = { version = "1.48", features = ["rt-multi-thread", "macros"] }
serde = { version = "1.0", features = ["derive"] }
surrealdb = { version = "2.3", features = ["kv-mem"] }

Key Files:

  • Root: /Cargo.toml (workspace definition)
  • Per-crate: /crates/*/Cargo.toml (individual dependencies)

Verification

# Build entire workspace (runs in parallel)
cargo build --workspace

# Run all tests across workspace
cargo test --workspace

# Check dependency graph
cargo tree

# Verify no circular dependencies
cargo tree --duplicates

# Build single crate (to verify independence)
cargo build -p vapora-backend
cargo build -p vapora-agents
cargo build -p vapora-llm-router

Expected Output:

  • All 13 crates compile without errors
  • 218+ tests pass
  • No circular dependency warnings
  • Each crate can be built independently

Consequences

Short-term

  • Initial setup requires understanding workspace structure
  • Developers must navigate between crates
  • Testing must run across multiple crates (slower than single tests, but faster than monolith)

Long-term

  • Easy to add new crates as features grow (already added doc-lifecycle, mcp-server in later phases)
  • Scaling to multiple teams: each team owns 2-3 crates with clear boundaries
  • Maintenance: updating shared types in vapora-shared propagates to all dependent crates automatically

Maintenance

  • Dependency Updates: Update in [workspace.dependencies] once, all crates use new version
  • Breaking Changes: Require coordination across crates if shared types change
  • Documentation: Each crate should document its dependencies and public API

References

  • Cargo Workspace Documentation
  • Root Cargo.toml: /Cargo.toml
  • Crate list: /crates/*/Cargo.toml
  • CI validation: .github/workflows/rust-ci.yml (builds --workspace)

Architecture Pattern: Monorepo with clear separation of concerns Related ADRs: ADR-002 (Axum), ADR-006 (Rig), ADR-013 (Knowledge Graph)