Architecture
This page describes the internal architecture of cuenv, explaining how the different components work together to provide typed environment management and task orchestration.
System Overview
Section titled “System Overview”cuenv is built as a layered system with clear separation of concerns:
┌─────────────────────────────────────────────────────────────┐│ cuenv-cli ││ (Command-line interface & user interaction) │├─────────────────────────────────────────────────────────────┤│ cuenv-core ││ (Tasks, environments, hooks, secrets, shell) │├─────────────────────────────────────────────────────────────┤│ cuengine ││ (CUE evaluation via Go FFI) │├─────────────────────────────────────────────────────────────┤│ Go CUE Runtime ││ (cuelang.org/go/cue) │└─────────────────────────────────────────────────────────────┘Crate Structure
Section titled “Crate Structure”cuengine
Section titled “cuengine”The CUE evaluation engine providing a safe Rust interface to the Go-based CUE evaluator.
Key responsibilities:
- FFI bridge between Rust and Go
- Safe memory management with RAII wrappers
- CUE expression evaluation
- Caching of evaluation results
- Retry logic for transient failures
Notable features:
CueEvaluator- Main evaluator type with builder pattern configurationCStringPtr- RAII wrapper for C strings returned from FFI- Response envelope parsing with structured error handling
- LRU cache for evaluation results
use cuengine::CueEvaluatorBuilder;
let evaluator = CueEvaluatorBuilder::new() .directory("./project") .package("cuenv") .build()?;
let result = evaluator.evaluate()?;cuenv-core
Section titled “cuenv-core”Core library containing shared types, configuration parsing, and domain logic.
Modules:
manifest- CUE manifest parsing and theCuenvtypetasks- Task definitions, execution, and dependenciesenvironment- Environment variable handling and validationhooks- Shell hooks for onEnter/onExit eventssecrets- Secret resolution and policy enforcementshell- Shell integration and export formattingcache- Task caching with content-aware invalidationconfig- Configuration file handling
Error handling:
Uses miette for rich diagnostic errors with:
- Source code snippets
- Error spans
- Contextual help messages
- Suggestions for fixes
use cuenv_core::{Error, Result};
#[derive(Error, Debug, Diagnostic)]pub enum Error { #[error("Configuration error: {message}")] #[diagnostic( code(cuenv::config::invalid), help("Check your env.cue configuration") )] Configuration { message: String },}cuenv-cli
Section titled “cuenv-cli”The command-line interface built with clap.
Commands:
cuenv task [name]- Execute or list taskscuenv env print|check|load- Environment operationscuenv exec -- <cmd>- Run commands with environmentcuenv shell init <shell>- Generate shell integrationcuenv allow|deny- Security approval managementcuenv version- Version information
cuenv-workspaces
Section titled “cuenv-workspaces”Workspace management for monorepos.
Features:
- Detect and configure workspaces
- Package manager integration (bun, pnpm, yarn, cargo)
- Workspace-aware task execution
FFI Bridge
Section titled “FFI Bridge”The Go-Rust FFI bridge is a critical component enabling CUE evaluation from Rust.
Go Side (bridge.go)
Section titled “Go Side (bridge.go)”// Exported functions callable from Rust//export cue_eval_packagefunc cue_eval_package(pathPtr *C.char, packagePtr *C.char) *C.char
//export cue_free_stringfunc cue_free_string(ptr *C.char)
//export cue_bridge_versionfunc cue_bridge_version() *C.charRust Side (cuengine)
Section titled “Rust Side (cuengine)”// FFI declarationsextern "C" { fn cue_eval_package(path: *const c_char, package: *const c_char) -> *mut c_char; fn cue_free_string(ptr: *mut c_char); fn cue_bridge_version() -> *mut c_char;}Response Envelope
Section titled “Response Envelope”All FFI responses use a structured JSON envelope:
{ "version": "1.0.0", "ok": { /* evaluation result */ }, "error": null}Or on error:
{ "version": "1.0.0", "ok": null, "error": { "code": "LOAD_INSTANCE", "message": "failed to load CUE instance", "hint": "Check that the package exists" }}Error Codes
Section titled “Error Codes”| Code | Description |
|---|---|
INVALID_INPUT | Invalid input parameters |
LOAD_INSTANCE | Failed to load CUE instance |
BUILD_VALUE | Failed to build CUE value |
ORDERED_JSON | JSON serialization failed |
PANIC_RECOVER | Recovered from Go panic |
JSON_MARSHAL_ERROR | JSON marshaling failed |
REGISTRY_INIT | Registry initialization failed |
Caching Architecture
Section titled “Caching Architecture”cuenv implements multiple caching layers:
CUE Evaluation Cache
Section titled “CUE Evaluation Cache”LRU cache for CUE evaluation results:
pub struct EvaluationCache { cache: LruCache<CacheKey, CachedResult>, max_size: usize,}Cache key components:
- Directory path
- Package name
- File content hashes
Task Cache
Section titled “Task Cache”Content-aware caching for task outputs:
~/.cache/cuenv/tasks/<hash>/├── metadata.json # Task metadata and input hashes├── stdout # Captured stdout├── stderr # Captured stderr└── outputs/ # Task output filesCache invalidation triggers:
- Input file changes (content hash)
- Task definition changes
- Environment variable changes
- cuenv version changes
Task Execution Model
Section titled “Task Execution Model”Dependency Resolution
Section titled “Dependency Resolution”Tasks form a directed acyclic graph (DAG) based on dependsOn:
┌─────┐ │build│ └──┬──┘ │ ┌─────┴─────┐ ▼ ▼ ┌─────┐ ┌─────┐ │lint │ │test │ └─────┘ └──┬──┘ │ ┌──┴──┐ ▼ ▼ ┌────┐┌────┐ │unit││e2e │ └────┘└────┘Execution Strategies
Section titled “Execution Strategies”- Sequential (array tasks): Execute in order
- Parallel (object tasks): Execute concurrently
- Dependent: Wait for dependencies to complete
Task Types
Section titled “Task Types”tasks: { // Single command build: { command: "cargo" args: ["build"] }
// Sequential list deploy: [ {command: "build"}, {command: "push"}, ]
// Nested (parallel groups) test: { unit: {command: "test-unit"} e2e: {command: "test-e2e"} }}Shell Integration
Section titled “Shell Integration”Hook Lifecycle
Section titled “Hook Lifecycle”cd /project/dir │ ▼┌──────────────┐│ cuenv detect │└──────┬───────┘ │ env.cue found ▼┌──────────────┐│ Check approval│└──────┬───────┘ │ approved ▼┌──────────────┐│ Load hooks ││ (background) │└──────┬───────┘ │ ▼┌──────────────┐│ Execute ││ onEnter │└──────┬───────┘ │ ▼┌──────────────┐│ Export env ││ to shell │└──────────────┘Security Model
Section titled “Security Model”- Approval Gate: Configurations must be explicitly approved before hooks run
- Content Hashing: Approval is invalidated when configuration changes
- Policy Enforcement: Secrets are only accessible to authorized tasks
Data Flow
Section titled “Data Flow”Environment Loading
Section titled “Environment Loading”env.cue ──► cuengine ──► Cuenv struct ──► Environment vars │ │ └── schema validation ────┘Task Execution
Section titled “Task Execution”cuenv task build │ ▼┌──────────────┐│ Parse config │└──────┬───────┘ │ ▼┌──────────────┐│ Resolve deps │└──────┬───────┘ │ ▼┌──────────────┐│ Check cache │└──────┬───────┘ │ miss ▼┌──────────────┐│ Load env │└──────┬───────┘ │ ▼┌──────────────┐│ Resolve ││ secrets │└──────┬───────┘ │ ▼┌──────────────┐│ Execute │└──────┬───────┘ │ ▼┌──────────────┐│ Update cache │└──────────────┘Future Architecture (Planned)
Section titled “Future Architecture (Planned)”Security Isolation
Section titled “Security Isolation”- Linux namespaces: Process isolation
- Landlock: Filesystem access control
- eBPF: System call monitoring
Distributed Execution
Section titled “Distributed Execution”- Remote cache backends
- Distributed task execution
- Build farm integration
See Also
Section titled “See Also”- Configuration Schema - Schema definitions
- Contributing - Development setup
- API Reference - Detailed API documentation