Skip to content

Architecture

FINOS CALM

banlieue describes its own architecture as code, in the FINOS Common Architecture Language Model (CALM). The model lives at docs/architecture/calm/architecture.json and the diagrams under this section are rendered from it by the CALM CLI — they are never hand-edited.

Why CALM

A README that says "the controller talks to the K8s API" is unverifiable. A CALM document encodes the same claim as structured data: there is a relationship of type connects from service-banlieue-controller to service-kubernetes-api, and the protocol is HTTPS. The renderer turns that into a Mermaid diagram; the validator turns it into a build failure when the model and the reality diverge.

The model also encodes our non-negotiables as controls (see below), so a reviewer can confirm at a glance that the architecture-as-code still matches the project's stated principles.

What's in the model

Section Count Examples
Nodes 16 actors, the management cluster, the controller, planned providers, every CRD
Relationships 13 every wire (connects), every container (composed-of), every consumer (interacts)
Flows 3 Create, Swap, Delete a VirtualMachine
Controls 3 CRD-only contract, code-first CRDs, supply-chain scanning

Each provider node carries its development phase in its display name ((planned, Phase 1B), etc.) so the picture is honest about what's implemented today vs the target architecture.

Rendered artefacts

  • System Diagram — every node and the wires between them, in a single Mermaid flowchart LR.
  • Architecture Flows — one Mermaid flowchart TD per business flow (Create, Swap, Delete), with each step labelled.

Both pages are regenerated by:

make calm-diagrams

make docs runs calm-diagrams first, so the published site is always in sync with the CALM model on disk.

Controls modelled in CALM

The CALM controls block is where banlieue's invariants are encoded as machine-readable requirements with links to evidence files and NIST references. Today:

Control What it asserts Evidence
crd-only-contract The controller MUST NOT speak RPC, REST, or gRPC to providers — only CRDs via the K8s API. CLAUDE.md, reasoning/crd-only-contract.md — NIST SP 800-53 SC-7, AC-4
code-first-crds All CRD YAML is generated from the Rust type system in banlieue-api via the crdgen binary; no hand-edited YAML. crates/banlieue-api/src/bin/crdgen.rs — NIST SP 800-218 SSDF PW.4, PS.1
capi-v1beta2-infra-machine-contract Every provider's infrastructure CRD satisfies the upstream Cluster API v1beta2 InfraMachine contract. crates/banlieue-api/src/infrastructure/vsphere_machine.rs, concepts/infra-crds-capi.md — CAPI v1beta2 InfraMachine
supply-chain-scanning CodeQL, cargo-deny, OpenSSF Scorecard, and SPDX headers on every source file. .github/workflows/, deny.toml — NIST SP 800-218 SSDF PO.5, PS.1, PW.4

Working with the model

Validate

make calm-validate

Validates architecture.json against the CALM 1.2 meta-schema. The CI workflow calm-test.yaml runs this on every push.

Re-render diagrams

make calm-diagrams

Re-runs the Handlebars templates in docs/architecture/calm/templates/mermaid/ and writes the output back into this directory.

Generate a richer doc site

make calm-docify

Uses calm docify (instead of calm template) and accepts the same template directory. The two commands produce equivalent output today; the docify form is reserved for future template bundles that emit multi-page documentation sites.

Add a new node, relationship, or flow

When you ship a new provider, subsystem, or backend:

  1. Add a node to architecture.json with a stable unique-id.
  2. Wire it into the right deployed-in / composed-of relationship (almost always rel-mgmt-cluster-contains-controllers or rel-kube-api-stores-crs).
  3. Add a connects relationship to the K8s API (every provider has one) and a second connects relationship to its backend.
  4. If a flow now traverses the new edge, add a transition to the relevant flow.
  5. Run make calm-validate && make calm-diagrams.

The full editor's guide lives at docs/architecture/calm/README.md.