Architecture
quicue.ca models any domain as typed dependency graphs in CUE. This document explains how the layers compose, what each module does, and how data flows from resource definitions to executable plans.
Four-layer model
Definition (vocab/) What things ARE and what you can DO to them
↓
Pattern (patterns/) How to analyze, bind, plan, and export
↓
Template (template/*/) Platform-specific action implementations
↓
Value (examples/, your code) Concrete infrastructure instances
Each layer imports only from the layer below it. CUE's type system enforces that values satisfy all constraints from every layer simultaneously — there is no runtime, no fallback, and no partial evaluation.
Module Dependency Graph
graph TD
vocab["vocab<br/><i>definition</i>"]
patterns["patterns<br/><i>definition</i>"]
templates["templates<br/><i>template</i>"]
orche["orche<br/><i>orchestration</i>"]
boot["boot<br/><i>orchestration</i>"]
wiki["wiki<br/><i>projection</i>"]
cab["cab<br/><i>reporting</i>"]
ou["ou<br/><i>interaction</i>"]
ci["ci<br/><i>ci</i>"]
server["server<br/><i>operations</i>"]
charter["charter<br/><i>constraint</i>"]
examples["examples<br/><i>value</i>"]
orche --> patterns
ou --> patterns
charter --> patterns
Layers
definition
- vocab — Core schemas: #Resource, #Action, #TypeRegistry, #ActionDef
- patterns — Algorithms: graph, bind, deploy, health, SPOF, viz, TOON, OpenAPI, validation
template
- templates — 29 platform-specific providers, each a self-contained CUE module
orchestration
- orche — Orchestration schemas: execution steps, federation, drift detection, Docker site bootstrap
- boot — Bootstrap schemas: #BootstrapResource, #BootstrapPlan, credential collectors
constraint
- charter — Constraint-first project planning: declare scope, evaluate gaps, track gates. SHACL gap report projection.
projection
- wiki — #WikiProjection — MkDocs site generation from resource graphs
reporting
- cab — Change Advisory Board reports: impact, blast radius, runbooks
interaction
- ou — Role-scoped views: #InteractionCtx narrows #ExecutionPlan by role, type, name, layer. Hydra W3C JSON-LD export.
ci
- ci — Reusable GitLab CI templates for CUE validation, export, topology, impact
operations
- server — FastAPI execution gateway for running infrastructure commands
value
- examples — 17 working examples from minimal 3-layer to full 30-resource datacenter
Definition layer: vocab/
#Resource
The foundation. Every infrastructure component is a #Resource:
dns: vocab.#Resource & {
name: "dns"
"@type": {LXCContainer: true, DNSServer: true}
depends_on: {router: true}
host: "pve-node1"
container_id: 101
ip: "198.51.100.211"
}
Key design decisions:
- Struct-as-set for
@typeanddepends_on.{LXCContainer: true}gives O(1) membership checks. Patterns testresource["@type"][SomeType] != _|_instead of iterating a list. - Generic field names.
host(notnode),container_id(notlxcid). Providers map generic names to platform-specific commands. - Open schema (
...). Resources can carry domain-specific fields without modifying vocab. - ASCII-safe identifiers. All resource names,
@typekeys,depends_onkeys are constrained to ASCII via#SafeIDand#SafeLabelregex patterns. This prevents zero-width unicode injection and homoglyph attacks at compile time.
#Action and #ActionDef
Actions are executable operations. Two schemas serve different purposes:
#Action— a resolved action with a concretecommandstring. This is what the binding layer produces.#ActionDef— an action definition with typed parameters and a command template. Providers declare these; the binding layer resolves them against resources.
// ActionDef (provider declares this)
ping: vocab.#ActionDef & {
name: "Ping"
description: "Test connectivity"
category: "info"
params: {ip: {from_field: "ip"}}
command_template: "ping -c 3 {ip}"
idempotent: true
}
The from_field key is what makes compile-time binding work. If a resource lacks the field a parameter needs, the action is silently omitted (not an error — the provider simply doesn't apply to that resource).
Pattern layer: patterns/
#BindCluster — command resolution
Matches providers to resources by @type overlap and resolves command templates:
cluster: patterns.#BindCluster & {
resources: _resources
providers: {
proxmox: patterns.#ProviderDecl & {
types: {LXCContainer: true, VirtualMachine: true}
registry: proxmox_patterns.#ProxmoxRegistry
}
}
}
// cluster.bound.dns.actions.proxmox.container_status.command = "pct status 101"
The binding algorithm:
- For each resource, iterate all providers
- If
provider.types ∩ resource["@type"] ≠ ∅, the provider matches - For each action in the provider's registry, check if all required parameters resolve from resource fields
- Resolve the command template with
#ResolveTemplate(compile-time substitution, up to 8 parameters) - Produce a concrete
vocab.#Actionwith the resolved command
#ExecutionPlan — the unifier
Composes binding, graph analysis, and deployment planning over the same resource set:
execution: patterns.#ExecutionPlan & {
resources: _resources
providers: _providers
}
// execution.cluster.bound — resources with resolved commands
// execution.graph.topology — dependency layers
// execution.plan.layers — ordered deployment with gates
CUE enforces that all three agree. If a resource's dependencies are inconsistent with its binding, evaluation fails — not at deploy time, at cue vet time.
Export projections
The execution plan can be projected into multiple output formats:
| Projection | Format | Target |
|---|---|---|
notebook |
.ipynb JSON |
Jupyter runbook with per-layer cells |
rundeck |
YAML | Rundeck job definitions |
http |
.http |
RFC 9110 REST Client files |
wiki |
Markdown | MkDocs site (index + per-resource pages) |
script |
Bash | Self-contained deployment script with parallelism |
ops |
JSON | Task list for cue cmd consumption |
| ## Extension modules |
ou/ — Role-scoped views
Role-scoped views that filter resources and actions by role: ops (full access), dev (read-only monitoring), readonly (status queries only). Exports W3C Hydra JSON-LD for semantic API navigation.
boot/ — Bootstrap sequencing
Credential collection and bootstrap ordering for initial infrastructure setup. Handles the chicken-and-egg problem (e.g., you need DNS to reach the vault, but you need the vault to configure DNS).
cab/ — Change Advisory Board
Generates CAB reports from impact analysis: what's changing, what's affected, what's the rollback plan, who needs to approve.
wiki/ — Documentation generation
Produces MkDocs-compatible markdown from the resource graph: index page, per-layer views, per-resource detail pages.
server/ — FastAPI gateway
HTTP API for executing resolved commands. Reads the CUE-generated OpenAPI spec and exposes actions as REST endpoints. Live at api.quicue.ca (public, mock mode).
kg/ — Knowledge graph
The .kb/ directory at the repo root is a multi-graph knowledge base with typed subdirectories (decisions/, patterns/, insights/, rejected/), each validated against its kg type.
Data flow summary
1. Define resources (CUE values with @type and depends_on)
↓
2. Declare providers (type matching + action registries)
↓
3. #ExecutionPlan unifies:
├── #BindCluster → resolved commands per resource per provider
├── #InfraGraph → depth, ancestors, topology, dependents
└── #DeploymentPlan → ordered layers with gates
↓
4. CUE validates everything simultaneously:
- Missing fields → compile error
- Dangling dependencies → validation error
- Type mismatches → unification error
↓
5. Export to any format:
- cue export -e output --out json → full execution data
- cue export -e execution.notebook → Jupyter runbook
- cue export -e execution.script --out text → deployment script
- cue export -e jsonld --out json → JSON-LD graph
Key Invariants
- No runtime template resolution. Every
{param}placeholder is resolved atcue vettime. If a command has an unresolved placeholder, it won't compile. - The graph is the source of truth. Deployment plans, rollback sequences, blast radius, documentation, and visualizations are all computed from the same unified constraint set.
- Struct-as-set everywhere.
@type,depends_on,provides, andtagsall use{key: true}structs for O(1) membership testing. - Hidden fields for export control. CUE exports all public fields. Intermediate computation uses hidden fields (
_depth,_ancestors,_graph) to prevent JSON bloat. - Topology-sensitive transitive closure. CUE's fixpoint computation for
_ancestorsis bottlenecked by fan-in (edge density), not node count.