Status
Everything in the first list runs today and is under test. Everything under the roadmap is a design or a deliberate deferral with no code behind it.
Implemented and tested
- Emet authoring language. Hindley-Milner types with generics, records
with row-polymorphic field access and update (
{ r | port = 443 }),case/ifwith exhaustiveness checking, single-constructor patterns in argument position (withPort p (Config spec) = …), numbers with infix operators, string interpolation, recursion and mutual recursion,Char, tuples and unit, and a minimal Elm-modeled module system (module … exposing,import … [as …] [exposing …], file = module). A program compiles a fleet:main : List Scroll. Diagnostics are Elm-style: source spans, did-you-mean, one report per error. - The four glyphs.
aptPackage,systemdService, the filesystem glyph (file/directory/symlink),lineInFile— every field a concrete string. Higher-level shapes are Emet functions that lower to these. See The four glyphs. - The binary manifest.
emetc buildemits a content-addressedManifest(postcard bytes, BLAKE3 per-scroll ids,format_version4 guard), with--textand--jsonviews. Determinism is enforced by golden-byte and round-trip tests. See Manifest format. - Recursive scrolls and per-leaf failure isolation. A
Scrollis a tree; each leaf is the unit of enact, retry, and rollback. One leaf’s failure never rolls back a sibling. See Reversible reconcile and A failing unit. - The retry and
on_exhaustcascade. A per-leaf retry budget (delay, backoff, jitter, attempt cap, wall-clock cap) resolved nearest-wins over the scroll’spolicychain andgolemd.toml’s[retry], withon_exhaust = rollback(default) orkeep. golemdingest + diff. Decode a manifest, select this host’s scroll, and diff it against the journal into orderedGlyphOps by glyph key and content id. Within a host: apt installs batched into one invocation, duplicate glyphs deduplicated, and units enacted in bounded parallel.- Reversible reconcilers. Each glyph’s
applycaptures anInversereceipt;reverserestores it exactly. Upgrade, removal, and rollback all derive from this. See Reversible reconcile. - Async apply with live progress.
POST /manifestanswers202 { reconcile_id }and the reconcile runs detached;golemctl applypolls it and renders a live per-unit tree, plain lines under--jsonor a pipe, and--reattachresumes an attempt whose connection dropped. golemctl plan. The same compile, no POST: what an apply would do, plus the systemd reloads it would trigger, changing nothing.notifiesreloads. A scroll declares units to reload once anything in or under it lands changed; a branch’s list unions down over every descendant leaf.- Fleet fan-out, client-side.
golemctl fleet apply|plan|statusfans a verb over a TOML inventory concurrently, one connection per host. One host’s failure never stops the others, and a host the manifest names no scroll for is skipped untouched. golemctl.apply,plan,fleet,state,history,show. HTTP:POST /manifest,POST /plan,GET /reconciles/latest,/reconciles/:id,/state,/revisions,/revisions/:id,/status. See the CLI reference.- SSH transport and the authorization gate. The agent binds loopback and
requires
Authorization: Bearer <token>against a configured token file;golemctltakes anssh://target or an inventorysshhost, opens the forward itself, and carries the secret. See Trust model. - Firewall drop-ins. An exposed
Quadletworkload emits one complete.nftfile per port opening under/etc/nftables.d/, plus the base chain and the oneshot unit that loads them — never a line appended to a shared file. See the Quadlet library. - The lichess fleet in Emet. A real multi-host deploy authored against a
shared Emet library (
examples/lichess/), compiling to scrolls of the four glyphs. See the tour.
Roadmap — not built
- Per-user identity. The agent binds loopback and requires one shared
bearer token, reached over an SSH forward
golemctlopens — that much is built. What is not: knowing which person submitted. Per-user tokens, an audit trail, and SSO group mapping arrive with an authentik-issued token replacing the shared secret. Manifest signing is not on the roadmap; the tunnel already holds that boundary. See Trust model. - Daemon-to-daemon propagation. Fan-out today is client-side:
golemctl fleetopens one connection per host from the operator’s machine. Agolemdthat hands a manifest to its peers — no operator machine in the loop — is designed (ADR 0039) and unbuilt. - Cross-host orchestration. Each
golemdacts only on its own scroll and knows nothing of its peers. There is no coordinator, no ordered drain, and no health-gated rollback across hosts:fleet applyreports each host’s outcome, and one host’s failure neither stops nor reverses another’s. - Resource kinds beyond the four glyphs. Containers, ingress, DNS, secrets — these are Emet abstractions (or future ones) that lower to the four glyphs, not new agent primitives. There is no secrets primitive and no DNS provider.
- Large-file and binary inverses. A
fileglyph’s inverse holds the prior contents inline in the journal. Out-of-line blob storage for large or binary files is deferred, so a very large managed file is not a shape to rely on yet.
What is gone
The older model — Blueprints, Hosts, Workloads, Services, Ingress as engine resource kinds, refcounting ownership across blueprints, and the Nickel authoring surface — has been removed. State is now per-scroll: a node’s desired state is one whole scroll, not a set of named blueprints that refcount shared resources.