Skip to content

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 @type and depends_on. {LXCContainer: true} gives O(1) membership checks. Patterns test resource["@type"][SomeType] != _|_ instead of iterating a list.
  • Generic field names. host (not node), container_id (not lxcid). 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, @type keys, depends_on keys are constrained to ASCII via #SafeID and #SafeLabel regex 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 concrete command string. 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:

  1. For each resource, iterate all providers
  2. If provider.types ∩ resource["@type"] ≠ ∅, the provider matches
  3. For each action in the provider's registry, check if all required parameters resolve from resource fields
  4. Resolve the command template with #ResolveTemplate (compile-time substitution, up to 8 parameters)
  5. Produce a concrete vocab.#Action with 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

  1. No runtime template resolution. Every {param} placeholder is resolved at cue vet time. If a command has an unresolved placeholder, it won't compile.
  2. 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.
  3. Struct-as-set everywhere. @type, depends_on, provides, and tags all use {key: true} structs for O(1) membership testing.
  4. Hidden fields for export control. CUE exports all public fields. Intermediate computation uses hidden fields (_depth, _ancestors, _graph) to prevent JSON bloat.
  5. Topology-sensitive transitive closure. CUE's fixpoint computation for _ancestors is bottlenecked by fan-in (edge density), not node count.