How the whole fleet fits together
One name, eight landscapes, one control plane
Every deployed workload has one four-part name: Landscape · Platform · Service · Module (LPSM).
A landscape fixes how a deployment behaves: its secrets, its data, its lifetime and its network edge. There are eight.
Primordial, the control plane, decides what should run. The serving clusters run it. If Primordial stops, traffic and login keep working; only deploys pause.
01 · Big picture
Five layers, one direction of control
Physically Git repositories on GitHub.com, plus an OCI registry where CI pushes the built images and charts.
fleet/registry/, each <platform>.carbon repo (example: argon.carbon) and each service repo (example: argon.zinc).fleet/platforms/. Example: Kargo edits platforms/argon/landscapes/pichu/zinc.yaml.Indigo frame = a human-edited folder; orange frame = a machine-edited folder. A human never edits platforms/.
Physically One virtual machine running k3s, a one-node Kubernetes cluster. When the VM boots, cloud-init decrypts its first secrets with SOPS and starts everything else.
primordial, and no user traffic reaches it.Source: concepts/seed-cluster.md (single-node k3s on one VM, SOPS via cloud-init) and ARCHITECTURE.md §3 (Infisical runs on Primordial; safe to be down for hours).
Physically Managed Kubernetes clusters at cloud providers: DigitalOcean, AWS and Oracle Cloud. fleet-operator creates each cluster through the provider's API.
<landscape>·<mark>. Example: raichu·opal. The mark (opal, ruby, emerald) tells you the provider."copper" is an example second service. Source: ARCHITECTURE.md §2 (cluster = landscape × mark; gems share a dataset) and §3 (provider load balancer, TLS at the Gateway).
Physically 3 kinds of machine: your laptop, a throwaway CI machine, and ENTEI (one shared Kubernetes cluster that hosts virtual clusters).
pls env up --profile <name>. Garden builds the whole instance. See section 08.Source: environments.md (profiles and hosts); ARCHITECTURE.md §3 (ENTEI hosts the vclusters and is never a serving landscape).
Physically Paid services from other companies, outside every cluster the fleet runs.
Control flows one way: Git → Primordial → clusters and vendors. Nothing below writes back up, except the machine-written fleet/platforms/ files.
*.carbon) ▼Pick a box above
Each box opens a plain description: what it does, where it runs, and which repo or node owns it.
Sources: ARCHITECTURE.md §1–§3, §8–§9; environments.md §1.
02 · LPSM, the one name
Four slots name every workload
The environment kind: raichu, lapras, castform…
A product family. Registered by creating its <p>.carbon repo. Example: mercury.
One repo, one deployable: <p>.<svc>. Example: argon.zinc.
One named piece inside a service: an API, a database (maindb), a cache.
- Hostnames are the coordinate reversed: module first, landscape last.
- Instance is not a fifth slot. It is added only where a physical name must be unique (one developer, one CI run, one preview).
- Cleanup never selects by instance. Cleanup uses allocation ID + generation.
Error records (the Problem custom resource) are named {service}.{module}.{landscape}.{version} today, which leaves out platform. A proposal to name them in full LPSM order is waiting on your answer in the error-records agenda item.
Sources: ARCHITECTURE.md §2, §7 (secret address), §9 (external names); goals/instance-segment-naming.md; goals/helm-wrapper.md (fullname rule).
03 · The eight landscapes
A landscape is a rule set, not a place
- A landscape fixes four rules: secret class, data posture, lifetime, network edge.
- Location is a property of a cluster. Consistency (one dataset) is a property of a landscape.
- Six landscapes are Garden workload profiles (development copies). Primordial and serving are not.
- A new landscape is a new row of settings, never new machinery.
- ENTEI is one registered cluster with role
anonymous-vcluster-hostandtraffic: false. - It hosts the eevee and castform virtual clusters (vclusters). It runs no application, no shared Logto and no shared database.
- It shares only the public gateway (kgateway), cert-manager, DNS/TLS for hosted names, and the exposure materializer.
- If ENTEI dies, eevee and castform go down together. Serving is not affected.
All six Garden profiles side by side build modes · data · secrets · edge
| Landscape | Runs on | Build modes | Data | Secrets | Edge |
|---|---|---|---|---|---|
| lapras | laptop k3d, kept | sync · build-local · target-pull | local CNPG, Dragonfly, MinIO, Mailpit, local Logto | read-only lapras seed; no writes | Boron direct to approved services |
| ditto | fresh cluster per test run | build-local · target-pull | deterministic fixtures | read-only ditto seed + demo credentials | loopback-only local kgateway |
| rotom | laptop k3d, offline, kept | sync only | signed offline bundle only | fake local store; zero keys | loopback-only local kgateway |
| absol | fresh cluster per run, offline | build-local from bundle | same bundle as rotom | fake local store; zero keys | loopback-only local kgateway |
| eevee | vcluster on ENTEI, one per person | sync · build-local · target-pull | local dependencies on host volumes | read-only eevee seed | ENTEI shared edge, real HTTPS |
| castform | vcluster on ENTEI, one per preview | target-pull only | forks of Neon, Upstash, Tigris | read-only castform seed + short-lived doors | ENTEI shared edge |
Build modes: sync = hot reload from source; build-local = build the image on this machine; target-pull = pull the exact image CI built (by digest).
Sources: environments.md §1, §1.1, §1.2, §1.3.
04 · How each landscape starts
Three ways in: bootstrap, Git, or pls
- The seed-cluster bootstrap creates Primordial, ArgoCD, Infisical and the fleet root app.
- Root of trust: the SOPS root key.
- After that, Primordial's own ArgoCD keeps it in line with Git.
- New landscape or cluster: one pull request to
fleet/registry/. - New platform: create the
<p>.carbonrepo. - New service: create the
<p>.<svc>repo. - Release: Kargo edits one row file per stage.
- On/off for traffic: set
traffic: true|falseon the cluster.
pls · the six Garden profiles
pls env up --profile <p>starts one.pls env down --profile <p>stops it.pls env doctorchecks it without changing anything.plsis the command-line tool shipped by thegarden-k3d-profilesnode; it runs Garden.
Sources: environments.md §1.3, §3; goals/garden-k3d-profiles.md (pls commands); goals/garden-vcluster-profiles.md (eevee, castform); goals/ci-k3d-lanes.md (nsc lanes); ARCHITECTURE.md §10–§11.
05 · Planes
Primordial decides, clusters serve
Nothing on a live request path depends on Primordial. Primordial composes desired state. If it is down for hours, deploys pause; traffic, failover and login keep working.
Primordial. ArgoCD, Kargo, the operators, Infisical. Outside the landscape registry. Never load-bearing for traffic.
Host-landscape clusters. Each sits behind a cloud load balancer with fixed IPs. TLS ends at the cluster gateway (cert-manager, Let's Encrypt).
Garden instances. k3d on laptops, nsc in CI, vclusters on ENTEI. Argo and Kargo never run inside these.
DNS + edge docs. Route 53 is primary, Cloudflare is secondary. The fleet, landscape and catalog docs are published twice: R2 and S3/CloudFront.
Every dependency has three layers
| Layer | What it is | Where it lives |
|---|---|---|
| Contract | Endpoint, credentials, behaviour. Same for every realization. | the app's config + secret names |
| Provisioning plane | Creates and resizes the dependency. Never on the traffic path. | Primordial (vendor APIs) |
| Data plane | The only layer that requests actually traverse. | vendor or in-cluster engine |
Delivery: where a dependency is realized
| delivery | Meaning | Used for |
|---|---|---|
| external | A vendor's data plane, reconciled from Primordial | Neon (Postgres), Upstash (KV), Tigris / R2 / S3 (storage) |
| replicated | Fanned out to every eligible cluster of the landscape | Dragonfly cache only (one instance per claim) |
| local | Applied directly inside one Garden instance | CNPG, MinIO, Dragonfly KV + cache, Mailpit |
The execution plane is the machinery that builds diene itself (the ratchet: nodes, rounds, reviews). Its identifiers never appear in shipped docs. See section 12.
Sources: ARCHITECTURE.md §1 (axiom 7), §3, §4, §7 (T4-LAYERS, delivery); environments.md §1.2; rules/AUTHORING-RULES.md (execution plane).
06 · Charts
The 2-chart law, used twice = 4 charts per platform
The design docs call this the 2-chart law (rule R20). A platform applies it twice: once for its carbon home repo and once per service. That gives the 4 chart kinds below.
Runtime only. Deployment, Service, the database-init hook Job.
Goes to every host cluster of each landscape. One Argo Application per service × landscape × cluster.
Custom resources only. PlatformDependency, WebhookRoute, Problem, LogtoApp…
Goes to Primordial. One Application per service × landscape.
The platform's namespace + SecretStore.
Goes to each host cluster. Services read secrets through this store.
Platform-shared CRs: ProviderAccount, shared PlatformDependency, WebhookEngine.
Goes to Primordial. The only render home for platform-shared dependencies.
diene-platform, the compiler chart, lives in fleet/registry/charts/. Per platform it renders the Platform CR, the Kargo pipelines and the platform ApplicationSet. It is Git-sourced on the moving tag machinery-stable; every other chart is published as OCI.
Counts follow ARCHITECTURE.md §8: g1 = one primordial Application per service × landscape; g2 = one app Application per service × landscape × cluster. Carbon is an ordinary chart-only service, so it counts as one more service here.
Where config values come from, in order last one wins
values.yaml: the chart's base.values.<landscape>.yaml: the landscape overlay.values.<cluster>.yaml: the cluster overlay, usually one identity value.- The row file's optional
values:block: a short-lived ops override, folded back into the chart at the next release. A probe flags overrides older than 7 days.
Landscape and cluster are two independent stacked dimensions, never one combined file.
Sources: ARCHITECTURE.md §1 (axiom 5), §8; rules/SAMPLE-CREATING-RULES.md R20; goals/charts/carbon.md; goals/helm-wrapper.md (overlays).
07 · Deploy, animated
Tap a repo, watch its charts land
platform.yaml.Top: GitHub. Middle: Primordial (one VM running a k3s cluster). Front: the 5 host clusters (example names). Right: services outside Primordial. 2 replicas per cluster is an example.
Tap argon.carbon to start.
Sources: ARCHITECTURE.md §8 (repos, discovery, three sources, g1/g2, Kargo per-service promotion, release trace), §9 (controllers), secrets-chain.md (Platform CR write path).
08 · Garden in motion
pls env up, piece by piece
pls drives it.Sources: environments.md §1.1–§1.4; goals/garden-k3d-profiles.md, goals/garden-vcluster-profiles.md, goals/ci-k3d-lanes.md; ARCHITECTURE.md §3, §4 (ENTEI traffic path).
09 · How a preview fork works
castform copies real data, then throws it away
- Dragonfly (cache or KV), MinIO, R2 and S3: the fork is refused with a
ForkUnsupportedcondition. Nothing is faked. - Local CNPG has no fork mechanic. A local module that needs real data uses a remote Neon branch instead.
Sources: environments.md §3 (preview model, R-P1…R-P9), §1.2 (castform row); goals/dependency-operator.md (fork mechanics table, broker-only creation); goals/fork-reaper.md (release steps); ARCHITECTURE.md §5 (forked identity safety).
10 · Multi-region
Login is global, data is local
- Home-sharding: each user has one home landscape per platform, stored as a claim in their identity.
- Production has two home landscapes today: raichu (Singapore) and ampharos (US).
- Each landscape has its own Logto issuer and its own dataset. There is no cross-region database.
- Caches stay regional with a time limit (TTL).
Names that span several landscapes use Route 53 geoproximity: one record set per landscape, nearest healthy one answers. Example: hooks.webhook.mercury.mew.cluster.atomi.cloud.
mew (production) and celebi (staging) are names only. They exist because OIDC browsers and webhook senders need one stable address that survives region changes.
That is a restore event, not a routing event: restore from cross-vendor backup and move the declaration. Expect hours (data loss window: minutes).
- AWS's strongly consistent multi-region options exclude Singapore (mid-2026), break EF Core, and cost 3–5× Neon.
- A globally consistent Redis does not exist.
Sources: ARCHITECTURE.md §2 (multi-region), §4 (geoproximity, edge docs), §5 (client flow, token lifetimes).
11 · Runtimes and runners
Five languages, one runner per job
Runtimes (what services are written in)
| Runtime | Templates | Libraries (lib/<lang>-*) |
|---|---|---|
| Bun (TypeScript) | bun-base, bun-lib, bun-cli, bun-consumer, nextjs-frontend | result, interfaces, core-utils, config, otel, problems, auth-engine, api-engine, frontend-utils, standard-config, e2e |
| .NET | dotnet-base, dotnet-lib, dotnet-api | result, interfaces, core-utils, config, otel, problems, auth-engine, api-engine, server-engine, standard-config, e2e |
| Go | go-base, go-lib, go-consumer, operator-template | errors-problems, interfaces, core-utils, config, otel, auth-engine, api-engine, standard-config, e2e |
| Dart / Flutter | dart-lib, flutter-base, flutter-e4 | result, problems, interfaces, core-utils, config, auth-engine, api-engine, e2e |
| Next.js (web) | nextjs-frontend, frontend-standalone-chart | uses the Bun libraries |
Every language starts its libraries in the same order: result → interfaces → core-utils.
Runners (what executes each job)
plsRuns the one deployment graph for all six development profiles. Owns up, down, reset.
Run Primordial and serving only. Argo syncs Git to clusters; Kargo promotes one service's release stage by stage.
CI. Runner label nscloud-ubuntu-26.04-amd64-16x32. Fallback: nscloud-ubuntu-24.04-amd64-16x32.
ditto and absol tests each get one throwaway nsc machine with built-in k3s, then nsc destroy --force.
The per-repo command surface: build, test, chart tasks. Files are .yaml.
Only two kinds: web frontends (Next.js) and erbium's error portal. Released as tagged versions through CloudflareDeploy.
Kubernetes substrates (where clusters come from)
| Substrate | Used by | Lifetime |
|---|---|---|
| k3d | lapras, rotom (laptop) | kept across down/up |
| nsc k3s | ditto, absol (CI) | one run, then destroyed |
| vcluster on ENTEI | eevee, castform | lease: days–weeks (eevee), 7-day renewable (castform) |
| Provider clusters | serving (DigitalOcean, AWS, OCI; EKS Auto Mode is the AWS direction) | permanent; removed only by Decommission |
EKS Auto Mode is "assumed green" (decision S11), not live-verified. Production use waits on your live test of aws-load-balancer-eip-allocations.
Sources: ARCHITECTURE.md §3, §3.1, §8, §10; environments.md §1.2; goals/ci-k3d-lanes.md; ratchet graph (nodes and edges, 2026-11-07).
12 · How diene itself is built
Templates branch on three switches
- Every template starts as a working sample repo that builds and passes CI.
- Templates form a tree from
workspace→shared. Each child removes or adds one capability. - The switches (dimensions): language, Helm on/off, Docker on/off, observability on/off.
Four kinds of link between nodes
| Link | Meaning | Example |
|---|---|---|
| template-depend | A template built on a parent template | shared → bun-base |
| template-materialize | Real code created from a template | bun-lib → lib/bun-result |
| library-depend | Code that uses a published library | lib/bun-result → lib/bun-config |
| execution-depend | Needs another node to run its proof | observability-block → bun-base-w-observability |
Build planes: from sample to a real repo
Working sample repos, e.g. helm-wrapper. Released as CyanPrint templates.
Real code materialized from a template, e.g. charts/carbon (copied from helm-wrapper).
Code turned back into a template, e.g. the new carbon-template node.
One real repo per platform or service, stamped with cyanprint create, e.g. mercury.carbon.
Sources: ratchet graph (node types template/code, edge kinds), carbon goal discussion; goals/workspace.md, goals/shared.md.
13 · Failure drill
Break one piece, see what still works
Sources: ARCHITECTURE.md §1 (axiom 7), §3, §4 (failure rungs, Cloudflare outage posture), §7 (vendor posture); environments.md §1.1 (ENTEI).
14 · Glossary
Every word on this page
- LPSM
- Landscape / Platform / Service / Module: the four-slot name of every deployed workload.
- Landscape
- A rule set for secrets, data, lifetime and network edge. One landscape = one consistent dataset per platform.
- Host landscape
- A landscape that owns clusters: pichu, pikachu, raichu, ampharos.
- Virtual landscape
- A DNS-only name over host landscapes: mew, celebi. Owns no clusters or data.
- Cluster mark
- A gem name (opal, ruby, emerald…) that shows the provider. A cluster = landscape × mark.
- Gem siblings
- Two clusters of one landscape, same dataset, used for blue/green cutover.
- Primordial
- The one permanent control-plane cluster: ArgoCD, Kargo, operators, Infisical.
- ENTEI
- The one host cluster for eevee and castform vclusters. Not a landscape.
- Instance
- One developer, run or preview inside a landscape. A naming add-on, not an LPSM slot.
- Allocation ID + generation
- The only key used to clean up or fence an instance.
- Garden
- The tool that runs the deployment graph for development profiles.
pls- The command-line tool that drives Garden:
pls env up,down,doctor. - vcluster
- A virtual Kubernetes cluster that runs inside a host cluster.
- Carbon
- A platform's home repo (
<p>.carbon). Creating it registers the platform. - Row
- One file per service per landscape in
fleet/platforms/<p>/landscapes/<l>/<svc>.yaml. Kargo edits it to promote. - T3 / fleet-operator
- The operator on Primordial with the cluster, platform, dependency, traffic, webhook and cf-deploy controllers. Graph node: dependency-operator.
- SoS
- Secrets-of-secrets: the Infisical project that holds each platform's machine credentials.
- ESO
- External Secrets Operator: copies secrets from Infisical into Kubernetes Secrets.
- forkSource
- castform's setting:
stagingorproduction. Production needs a separate grant and allows one preview at a time. - Decommission
- The explicit custom resource that deletes something for real. Deleting a repo or a CR alone never destroys data.
15 · Your open decisions
Eight cards, answers first
- Eight questions from the build engine are waiting on your answer. Each tab is one card: the question first, then the concepts you need, where things stand, and links.
- Nothing merges by itself. Review pages are for reading and comments; your answer on the card is what unblocks work.
- Unit: one template or library the engine builds and checks on its own, e.g.
bun-base. The tree of units is in How diene is built. - Round: one finished chunk of a unit's work, checked by the engine before it is shown to you.
- Review: a GitHub pull request you read and comment on. Approving records your OK; it never merges anything.
- Held: the engine will not finish a held unit until you answer.
- Mirror: a unit's own public GitHub repo in the ProtoDurian organization. Review pages live in
ProtoDurian/diene.all; goal drafts (what "done" means for a unit) live inProtoDurian/diene-corpus.
Approve the monitoring add-on's rewrite (work rounds 12 to 17), or ask for changes on its review page.
-w-observability then come to you for review, one by one.observability-block: monitoring documentation, five Grafana skills and a dashboard sandbox, built on the shared template and mixed into every template ending in -w-observability. How diene is built- Rounds 12 to 17 are ready for your approval together; the checks on the public mirror are green (3 of 3).
- Your three picks are in: the log-panel table with evidence panels, text panels to introduce sections, and the longer log-level format list.
- A fresh agent ran all five skills using only these docs: 5 of 5 passed.
- The query-check tool does not block this approval.
- Review page: rounds 16 to 17 — everything since the version you last looked at; 15 files, documentation only.
- The full rewrite: rounds 12 to 15 — the version you already reviewed; 41 files.
- Query-check goal draft — the new tool's goal, for your review; its checks fail on purpose until the engine gives the tool its own unit.
Nothing to decide yet. Your feedback is in; lib/bun-result is being fixed and its review comes back to this card. Approving that review publishes version 1.1.0.
map. No API change; async stays async.should helper such as await actual.should.be.equal(expected).result, then interfaces, then core-utils. Runtimes and librariesOk (a value) or Err (a failure) instead of a thrown error. Example: Ok(5), Err('bad').isOkSync() and isErrSync(): instant checks, meant for when the answer is already known. Two cases still throw today; both are fixed this round.- Fix order:
bun-base, then the four library templates, thenlib/bun-resultwith theshouldhelper and both sync fixes. - The consumer-test rule is merged into the goal files (link below).
dart-libis the first template with the consumer test: its round 19 landed, checks green, reviewer approved; its review is queued.- When
lib/bun-resultlands, a new review page comes to this card; approving it publishes 1.1.0 to npm, the public JavaScript package store.
- lib/bun-result review page — the version already open; it shows only what
lib/bun-resultadds on top ofbun-lib. - Consumer-test rule — the goal-file change, already merged.
Two answers, ruled as a pair: confirm that a new carbon-template unit publishes the carbon template, and choose how mercury.carbon gets made — hand-built once (recommended) or stamped by the engine.
carbon-template unit publishes the template; a person runs the scaffold once and edits platform.yaml. Carbon's hold lifts immediately.mercury.carbon, re-stamping it when the template changes. No new unit, but carbon mixes a Helm chart pair with a scaffold generator.mercury.carbon. Creating that repo is what registers a platform. Glossarycharts/carbon is the code (a Helm chart pair); carbon-template is the new publish step; each platform's carbon repo is an instance. How diene is built- Your carbon-template pick is held until you confirm it;
charts/carbonstays held on this pair; nothing was reverted. - 14 units wait behind carbon (fork-reaper, the Garden profile units, logto-operator, mercury and others); they are not held themselves.
- This ruling removes one blocker, not all: carbon also waits on other open questions through its parent units.
- Everything here is at zero; no deadlines.
- carbon-template goal draft — written, but unmerged until you confirm your pick.
Three answers on error records: confirm that the module is part of a record's identity; rename records to LPSM order (recommended); let each app template own its error-portal pieces (recommended).
lapras.nitroso.zinc.api.v1 (landscape.platform.service.module.version). Same order as the error pages' URLs; readable on its own; cheap now because nothing is published yet.zinc.api.lapras.v1 (service.module.landscape.version). Platform lives in the Kubernetes namespace, so the name skips it.Problem) per landscape + platform + service + module + version, listing every error a service can return: id, HTTP status, retryable or not, data shape. The naming note in LPSM names is this very question.bun-consumer, dotnet-api, go-consumer (back ends), nextjs-frontend (web), flutter-base (mobile). Runtimes and libraries- Your "module counts" pick is held as a draft until you confirm.
- Nothing is published under the current name; renaming touches only the four problems libraries and two goal files.
- error-portal is held as a draft; nothing sits downstream of it.
- None on this card.
Decide the mobile template's shape: split flutter-base into a v1 unit plus a later flutter-e4 unit (already drawn, nothing built), or keep one unit — and if split, two follow-up answers.
flutter-base.-w-observability templates.- Both flutter units are paused on this card; the split is kept in the graph, not undone, and nothing has climbed.
- The two follow-ups (adapter owner, link checks) only matter if the split stays.
- None on this card.
Give the two naming libraries publishing homes: their own repos with the usual diene names (recommended), their own repos with names you pick, or folders inside their parents' repos.
diene.instance-segment-naming and diene.fork-name-qualifier. No re-checks, no patch rounds.- Both units are held here and on the preview fingerprint decision (Preview pieces tab); both rulings must land before either starts.
- 11 units wait behind
instance-segment-naming; 4 sit downstream offork-name-qualifier. - No deadlines — but a published name is the name you keep.
- None on this card.
Pick the owner of the two trusted preview pieces: a new preview-assembler unit builds the fingerprint and the assembler (recommended), or the existing fork-reaper absorbs them.
- Nothing is ruled and nothing is built: 6 units are held on this, plus 11 behind them.
- Two of those units also wait on the naming-libraries decision; both cards must clear to free them.
- None on this card.
Approve the five template reviews that are next, top-down — or comment on a review page and ask for changes.
bun install, and the Express example leaves the validation doc. Then the Bun chain (bun-lib, bun-cli, releaser) comes next.go-lib sits under it.bun-base and dotnet-base changed after your last approval; the other three have never been reviewed.- Five reviews are truly next;
bun-base-wo-helmandbun-base-wo-helm-dockerfollow, only afterbun-base. - Approving one sends its children's reviews to this card next.
- After these five, the queue unlocks top-down: the Bun libraries, the .NET chain,
dart-lib, then the eight charts.
- bun-base review — rounds 11–14, 17 files.
- dotnet-base review — rounds 10–14, 8 files.
- shared-wo-docker-helm review — first review, 32 files.
- helm-wrapper review — first review, 98 files.
- go-base-wo-helm review — first review, 31 files.
Sources: the eight open decision cards, 2026-11-07. Concept links point at the sections above on this page.