akua is one binary, end-to-end. Every verb is a transformation on typed inputs producing typed, signed, deterministic outputs. No hidden services, no control plane, no required cluster. The CLI does the work; the SDK exposes the same work to library consumers; the browser runs the same work in WebAssembly.
This document describes the target architecture. Implementation is tracked in roadmap.md and the masterplan.
author compile consume
────── ─────── ───────
KCL Package ──▶ akua render ──▶ reconcilers:
(*.k + akua.toml) │ ArgoCD / Flux / kro
│ Helm release lifecycle
Rego Policy ──▶ ├─ embedded kubectl / Crossplane
(*.rego) │ engines:
│ KCL
@ui decorators ──▶ │ Helm v4
(on KCL schemas) │ OPA + Regal
│
│ Kyverno→Rego
akua.toml + akua.lock ──▶ │ CEL
(human intent + │ Kustomize
digest-pinned ledger) │ kro (offline)
│
└─ akua publish ──▶ OCI registry
(signed + SLSA) (cosign + SLSA v1)
Three stages, each independently pluggable. See docs/package-format.md and docs/policy-format.md for the authoring shape; docs/cli.md for every verb; docs/sdk.md for library-consumer shape.
| consumer | surface | when used |
|---|---|---|
CLI — akua binary |
26 shipped verbs + ~10 planned (see cli.md) |
developers, CI, agents in sandboxes |
SDK — @akua-dev/sdk |
same capabilities, Node/Bun-native | backend services that embed akua in-process |
Browser — playground at akua.dev + local akua dev UI |
subset that compiles to WebAssembly | authoring, review, live-preview |
Trust contract: the binary, the SDK, and the browser produce byte-identical output for the same inputs. No "the real thing is behind the paywall." A backend service calling @akua-dev/sdk.render() gets the same bytes a developer gets from akua render in their terminal.
See docs/cli-contract.md for the universal contract every consumer honors.
All engines bundled into the binary via wasmtime. $PATH is never required and there is no shell-out escape hatch — CLAUDE.md's "No shell-out, ever" invariant holds across the render pipeline.
See docs/embedded-engines.md for the embedding contract, version pinning, and size budget.
- Packages — authored in KCL (
Package.kwith three regions: imports / schema / body). Published as signed OCI artifacts.akua renderemits raw YAML, one file per resource. Seedocs/package-format.md. - Policies — authored in Rego. Kyverno / CEL / foreign Rego modules are consumed as compile-resolved imports via
akua.toml, not runtime string lookups. - Higher-level workspace concepts (App, Environment, Cluster, Secret, Gateway, Workspace, PolicySet, …) — user-defined KCL schemas in the consumer's own workspace, shaped to their deployment reality. akua does not ship a KRM vocabulary. Reconcilers (ArgoCD / Flux / kro) consume the raw-Kubernetes output of
akua render; they don't need akua-specific kinds.
Same inputs + same akua.lock + same akua version → byte-identical output. No now(), no random(), no env reads, no filesystem reads, no cluster reads inside the render pipeline.
See design-notes.md §engine-determinism for the pragmatic trade-offs (why Helm stays non-pure even though pure-functional would be cleaner).
akua publish emits a cosign signature plus a SLSA v1 predicate unless the caller explicitly opts out. Consumers verify by default on pull. See docs/lockfile-format.md and docs/cli.md publish / verify.
- Not a reconciler. ArgoCD, Flux, kro, kubectl own the cluster side.
- Not a Kubernetes control plane. No controllers, no CRDs of our own running against customer clusters.
- Not a non-Kubernetes deploy target. We emit formats Kubernetes-ecosystem reconcilers consume. Fly Machines / Cloudflare Workers / AWS Lambda are out of scope.
- Not a curated package catalog. Upstream projects publish their own signed packages; we ship the substrate.