How diene runs

11 · Whole-system test

The whole system, tested for real

A working proof on real clusters: new platform = just a repo, new service = just a repo, failovers, Logto across regions. Results land here when the test ends.

  • Owner ruling: build a whole working proof, keep cost low. DECIDED · owner D37
  • It may use ProtoDurian and up to USD 100. DECIDED · owner D38
  • Cloudflare only under dpoc.specpenguin.dev; free Vercel is fine. DECIDED · owner D39

Already proven: a live move under heavy traffic

  • Three machines in Singapore: an old Postgres, a new Postgres, and 8 app processes with the library. TESTED · spike L
  • A no-error move works up to 100,000 writes a second, plus 300,000 reads a second. Every rate: 0 failed, 0 lost, 0 doubled. TESTED · spike L
  • Writes wait a moment once; reads never pause. TESTED · spike L
Write pause during a live Postgres move, by write rate TESTED · spike L, spikes2/l-load/REPORT.md
1,000 writes/s76 ms
5,000 writes/s54 ms
20,000 writes/s75 ms
50,000 writes/s509 ms
100,000, 2 subscriptions writes/s3.2 s
100,000, 1 subscription writes/s6.1 s
100,000, 8 subscriptions writes/s8.1 s and 18.1 s

Bar length is on a log scale (each step is 10× longer). Every rate: 0 failed, 0 lost. Reads never paused.

The numbers as a table
Writes / sVerdictFailed / lostHold
1,000PROVEN0 / 076 ms
5,000PROVEN0 / 054 ms
20,000PROVEN0 / 075 ms
50,000PROVEN0 / 0509 ms
100,000, 2 subscriptionsPROVEN0 / 03.2 s
100,000, 1 subscriptionPROVEN0 / 06.1 s
100,000, 8 subscriptionsPROVEN0 / 08.1 s and 18.1 s
100,000, 4 subs, small batchesNOT REACHED–replication never caught up
  • While writes wait, they sit in a queue in the app's memory: 2.58 million writes waited 46 s across 8 apps, then went through in under 7 s with 0 errors. TESTED · spike L
  • So memory is not what breaks first; the caller's own time limit is. TESTED · spike L

The whole-system test

How it works

Copied from poc/HOW-IT-WORKS.md as it stood at 2026-11-12 07:02 UTC. Its layout here is plain for now.

Answer first: a team makes a GitHub repo and pushes a version tag. Everything after that is automatic: the platform and service are found by their repo names, Kargo walks the version through the landscapes, Argo CD deploys it, and T3 (our operator) builds the databases, writes the secrets, keeps DNS pointed at healthy clusters, and publishes the address books that let apps survive a dead cluster or a dead DNS host.

Status tags used below: BUILT+TESTED (ran in the PoC, numbers in REPORT.md / drills.json) · BUILT (running, drill pending) · DESIGN ONLY (from the corpus, not built here) · CHANGED (the design had to change to work; see CHALLENGES.md).

1. The pieces (what exists)
PieceWhereWho changes it
dpoc-fleet repoGitHub ProtoDurian👤 people: registry/ (landscapes, clusters, accounts) · 🧱 rare: machinery/
dpoc-fleet-state repoGitHub (mirror of the bot git server)🤖 machines only: T3 writes stubs, Kargo writes versions
dpoc-<platform>.carbonone repo per platform👤 platform team: platform.yaml (landscapes, release order, maturity)
dpoc-<platform>.<service>one repo per service👤 service team: code + 2 charts
Primordial clusterdpoc-primruns Argo CD, Kargo, T3. Not in the request path.
Workload clusterspichu-opal, raichu-opal, raichu-ruby, ampharos-opalrun the apps, one Logto per landscape
T3 operatoron Primordialcluster, materializer, dependency, logto, traffic, edge controllers

Repos in the PoC: dpoc-fleet, dpoc-fleet-state, dpoc-nitroso.carbon, dpoc-nitroso.tin (bun API), dpoc-nitroso.web (frontend), dpoc-aldehyde.carbon, dpoc-aldehyde.lithium (Logto), and – created during the run – dpoc-argon.carbon, dpoc-argon.zinc.

Picture: see the diagram above.

2. Who writes what (every folder has ONE kind of writer)
FileWriterWhenDepth from a human act
dpoc-fleet/registry/clusters/raichu-ruby.yaml👤 person, by PRa new cluster0
dpoc-fleet/machinery/*🧱 person, rarethe system itself changes0
dpoc-fleet-state/platforms/nitroso/tin/pichu.yaml pin:🤖 Kargoevery release, per stage2 (tag → CI → Kargo)
same file, first creation (empty pins)🤖 T3 materializera repo dpoc-nitroso.tin appears1
same file, values:👤 person, emergency onlyrare0
dpoc-nitroso.carbon/platform.yaml👤 platform teamnew landscape for the platform0
dpoc-nitroso.tin/infra/primordial/... (Database, KeyValue...)👤 service teamneeds a dependency0
Secret tin-database-main in every cluster🤖 T3 dependency controllerrecord Ready / rotation / move1
DNS records under c. and cf.dpoc.specpenguin.dev🤖 T3 traffic controllerevery 5 s, only on change1
Edge docs fleet.json, selector/<p>.json, catalog/<p>.json🤖 T3 edge controlleron change1

Row file (contract), e.g. platforms/nitroso/tin/pichu.yaml:

platform: nitroso
service: tin
landscape: pichu
pin: {primordial: "1.0.0", chart: "1.0.0", image: "1.0.0"}   # Kargo; "" = not deployed
values: {}                                                       # human emergency override, Kargo never touches it

CHANGED: the machine rows live in their own repo (pick 4b) and are written to a bot git server first, then mirrored to GitHub (the org blocks deploy keys; CHALLENGES 1).

3. Deploy order (empty system → first user), as run
  1. L0 seed (by hand, once): clusters exist; Argo CD + Kargo + cert-manager on Primordial; Secrets for vendor tokens, the CA, one credential per cluster; kubectl apply -f machinery/fleet-root.yaml.
  2. fleet-root syncs the CRDs, T3, the platforms AppSet, the baseline AppSet and registry/ (Landscapes, ClusterRegistrations).
  3. T3 cluster controller: each ClusterRegistration → Argo CD cluster Secret with labels landscape, mark + a gateway certificate in that cluster.
  4. baseline AppSet: every labelled cluster gets the gateway health responder + default TLS store (seen: all 4 clusters in < 1 min, no human step).
  5. platforms AppSet finds dpoc-*.carbon repos → one platform-<p> app → Kargo Project + the platform's AppSets.
  6. T3 materializer finds dpoc-<p>.<svc> repos → stub rows for every landscape in platform.yaml.
  7. Per service: a pipeline app renders the Kargo Warehouse + Stages from stages: [pichu, [raichu, ampharos]].
  8. Logto first (platform aldehyde, service lithium): its Database record → T3 makes a Neon database in that landscape's region → Logto starts (2 replicas per cluster) → T3 boot-seeds its own admin app.
  9. Services (tin, web): Database/KeyValue/Store/Email + LogtoApp records → T3 builds them → app pods start (they cannot start without the database secret) → Argo CD reports Healthy only when the records are Ready.
  10. Traffic: T3 probes every cluster every 5 s and writes the A-sets; edge docs are published to two hosts.

Picture: see the diagram above.

4. Release flow (v1 → v2, a broken v3)
  • One version = image + app chart + primordial chart at the same semver; a half-published release makes no Freight.
  • Kargo writes the pin into the first stage's row; the Stage is Healthy only when every Application of that row (Primordial + every cluster) is Healthy at that version; then the next stages get it.
  • A broken version stops at the first stage (pichu); raichu and ampharos stay on the old one. BUILT (drill 3 numbers in drills.json).
5. The controllers (T3, one process on Primordial)
ControllerInputOutputNotes
clusterClusterRegistrationArgo CD cluster Secret (+labels), gateway cert (SAN *.<p>.<l>.<root> per platform)CHANGED: cert re-issued when a platform appears
materializerGitHub repo names dpoc-<p>.<svc>stub rows in fleet-statenever edits/deletes a row; unauthenticated GitHub = 60 calls/h → 2-min poll (CHALLENGES 3)
dependencyDatabase, KeyValue, Store, Email (dictionary-keyed modules)Neon / PlanetScale / Upstash / Tigris resources + Secret <svc>-<class>-<module> in every cluster of the landscapeledger in Tigris (intent → create → confirm), two-generation rotation, one live vendor move
logtoLogto per landscape + LogtoApp recordsboot-seed admin app, API resources, apps, client ids as Secretscreate-once (the Secret is the commit point)
trafficClusterRegistration + 5 s probesA-sets on Route 53 + DigitalOcean (main root) and Cloudflare (spare root)brakes: never remove the last address, freeze when > half look down, lease so only one writer
edgeplatforms × landscapes × servicesDoc A/B/C on Tigris + S3/CloudFrontmonotonic versions, 60 s cache
6. Names and DNS roots
  • App name = <service>.<platform>.<landscape>.<root> (LPSM reversed), e.g. tin.nitroso.raichu.c.dpoc.specpenguin.dev.
  • Logto issuer per landscape: https://lithium.aldehyde.<landscape>.c.dpoc.specpenguin.dev/oidc – baked into apps, never read from a doc.
  • Roots (PROPOSAL-DNS option 4, with the hosts we have):
RootServed byRole
c.dpoc.specpenguin.devRoute 53 and DigitalOcean DNS (one zone, two hosts; Cloudflare's delegation lists both)main name
cf.dpoc.specpenguin.devCloudflarespare name (stand-in for a spare domain on another TLD)
  • Records per root R and landscape L: L.R A = healthy cluster IPs (TTL 60) · *.L.R CNAME → L.R · <mark>.L.R A = one cluster (dark-verify).

Picture: see the diagram above.

7. Edge documents (the address books)
DocPathHoldsWhen the client reads it
A fleetfleet.jsonwhere the other docs live (Tigris + CloudFront)refreshed in the background
B selectorselector/<p>.jsonwhich landscapes the platform runs in (names, regions)sign-up, to pick a home
C catalogcatalog/<p>.jsonper landscape × service: ordered full addresses (main root first, spare after)only when the rescue router trips

Hosts: Tigris public bucket dpoc-edge and AWS S3 + CloudFront. No signing: the client only accepts addresses ending in .dpoc.specpenguin.dev.

8. Sign-in per region (Logto)
  • One Logto issuer per landscape (pichu, raichu, ampharos), each with its own database in its own region (Neon Singapore / Oregon), at least 2 replicas per cluster; raichu runs on 2 clusters = 4 replicas sharing one database.
  • A user's home landscape is a claim; the client always talks to its home's issuer and API. A dead home region = restore event, not a routing event (home-sharding).
  • Access token 10 min, refresh token 14 days rotating. If the issuer's DNS name dies, signed-in users keep working until the pass ends; nobody new signs in (G5 position).
9. Failover paths (what saves the user)
What breaksWhat saves the userTime
one podKubernetes + readiness0 errors
one nodethe cloud LB's own health checks0 errors
one cluster of a landscapeclient tries the next address (multi-A) + retry once; T3 removes it from DNS after 3 failed 5 s checksuser errors ≈ 0 with retry; DNS clean in ~13–19 s + TTL
Route 53 downDigitalOcean answers the same zone0 errors (two hosts)
the whole main root deadrescue router: Doc C → spare root cf.first failing request + one doc fetch
Primordial downnothing reactive depends on it: apps keep serving, DNS frozen at last good state0 errors; deploys pause
frontend host downCNAME flip to the standby (stand-in)DNS TTL
10. Mercury (webhooks) — DESIGN ONLY in this PoC unless REPORT.md says otherwise

Mercury is the fleet's shared webhook service: an ordinary bun service on its own platform, one intake per serving landscape, behind the same gray DNS. It accepts a vendor's webhook, stores the event in that landscape's Upstash KV, then probes every candidate subscriber at delivery time: exactly one 200 (the owner) and every other 421 ("not mine") completes the delivery; anything else refuses loudly and retries the whole set later (72 h obligation, then dead letter). If every intake is down, the vendors' own retries cover the gap.

11. Every place the design had to change (details in CHALLENGES.md)
  1. Bot writes to GitHub: no deploy keys in the org → bot git server + mirror (corpus: name a GitHub App).
  2. Images: ghcr refused org CI → own registry.
  3. GitHub discovery without a token: 60 calls/h → slow polls (corpus: GitHub App + webhooks).
  4. Carbon chart names must follow dpoc-<p>-carbon.
  5. Spare DNS name cannot be independent without a second domain.
  6. TLS certs need one wildcard per platform (re-issued by T3).
  7. Logto's own app records cannot live in Logto's chart (Argo sync would wait on itself).

Result pending

Drill by drill

A timeline per drill: what happened at t = 0, and what the user saw.

Fills in by itself from poc/drills.json when it lands.

Result pending

What broke, what the design must change, cost

The test report.

Fills in by itself from poc/REPORT.md when it lands.

Challenges

Copied from poc/CHALLENGES.md as it stood at 2026-11-12 07:15 UTC. Its layout here is plain for now.

Each row: what broke or was unclear · what the PoC did · does the corpus need a change. Status words: FIXED IN POC (worked around and the fix is proven) · OPEN (owner must choose) · NOTE (small).

1. Machines cannot write to GitHub without a broad credential — FIXED IN POC (workaround) · corpus MUST change
  • What happened: Kargo and T3 must push version pins and stub rows to dpoc-fleet-state. The ProtoDurian org disables deploy keys ("Deploy keys are disabled for this repository"). The only token on hand is the owner's gh login token (admin:org, repo on every repo).
  • Example: putting that token on a droplet would let anything on it rewrite any repo of the owner.
  • PoC fix: bots push to a small git server on the build machine (git.dpoc.specpenguin.dev, Gitea); a relay on the lead's box mirrors it to GitHub every 3 s. The GitHub copy is what Argo CD reads, so GitHub stays the source of truth people see.
  • Corpus change: name the credential: one GitHub App on the org with contents: write on fleet-state only (Kargo + T3) and metadata: read on the org (discovery). The design says "the fleet-write credential lives here" but never says what it is.
2. Container images cannot be published to ghcr.io from org CI — FIXED IN POC (workaround) · corpus should change
  • What happened: a workflow with packages: write pushing ghcr.io/protodurian/dpoc-probe got denied (org package policy; no API to change it).
  • PoC fix: a registry on the build machine, reg.dpoc.specpenguin.dev (Let's Encrypt TLS, anyone can pull, push needs a password kept as a GitHub repo secret).
  • Corpus change: the release CI section should say which registry and which org setting it needs ("allow GitHub Actions to create packages"), and that new ghcr packages start private, so clusters need a pull credential or a visibility step.
3. Unauthenticated GitHub discovery runs out of calls — FIXED IN POC (slower) · corpus should change
  • What happened: the platforms AppSet (SCM generator) and the T3 materializer both list the org's repos. Without a token GitHub allows 60 calls an hour per IP; at 90 s + 60 s polling we were at 32 left after 10 minutes.
  • PoC fix: SCM generator every 180 s, materializer every 120 s, ETag caching. Result: a new repo is noticed in up to 3 minutes.
  • Corpus change: same GitHub App as item 1 (5,000 calls/h) + a GitHub webhook to the AppSet controller, so "new repo → pipeline" is seconds, not minutes.
4. Carbon is a "service" too, so its charts must follow the service name rule — FIXED IN POC · corpus NOTE
  • What happened: the compiler expects charts dpoc-<p>-<svc> and -primordial. The carbon repo first published dpoc-nitroso (no -carbon), so its pipeline waited forever with no error.
  • PoC fix: carbon charts are dpoc-<p>-carbon / dpoc-<p>-carbon-primordial; carbon's Warehouse has no image subscription (spike A hole 12).
  • Corpus change: state the carbon chart names and the image-less Warehouse in fleet.md.
5. The spare DNS name is not independent here — OPEN (needs a second domain)
  • What happened: everything lives under specpenguin.dev, a Cloudflare zone. The proposal (PROPOSAL-DNS.md option 4) wants the spare base on another domain, TLD and registrar.
  • PoC fix: main root c.dpoc.specpenguin.dev is one zone on two hosts (Route 53 + DigitalOcean, the proposal's two-host shape with DigitalOcean standing in for Google). Spare stand-in cf.dpoc.specpenguin.dev lives on Cloudflare.
  • What this cannot show: "Cloudflare (the parent) is dead" – both names die with it. A truly independent spare needs a second domain on another host.
6. One-label TLS wildcards vs dotted LPSM names — FIXED IN POC · corpus NOTE
  • What happened: tin.nitroso.pichu.c.dpoc… is two labels under the landscape; *.pichu.c.dpoc… does not cover it.
  • PoC fix: each cluster's certificate carries *.<platform>.<landscape>.<root> for every platform; T3 re-issues it when a new platform appears (seen live: 9 → 12 → 15 names as nitroso and aldehyde arrived). DNS needs only *.<landscape>.<root> (DNS wildcards match any depth).
  • Corpus change: say the cert SAN set grows per platform, and who re-issues it.
7. Workload cluster API addresses must be reachable from Primordial pods — NOTE
  • What happened: the provisioning credential used the docker container name; Primordial pods could not resolve it (Was there a typo in the url or port?). Also the CA field was stored base64 twice. Both fixed in minutes.
  • Corpus change: none; the cluster controller DoD should include "Primordial can reach every cluster API" as a status condition.
8. Logto needs a database login that can create roles — FIXED IN POC · corpus MUST change
  • What happened: logto db seed failed on Neon: permission denied to create role (42501, "Only roles with the CREATEROLE attribute may create roles"). T3's two-generation logins (app_a/app_b) are plain app logins.
  • PoC fix: generation logins get CREATEROLE.
  • Corpus change: the Database record needs a privilege field (e.g. privileges: app | admin), and the rotation section must say what happens to roles the app itself created (Logto creates logto_tenant_* roles owned by whichever generation ran the seed).
9. A T3 restart rotates every database password — FIXED IN POC by not restarting during drills · corpus note
  • What happened: the PoC keeps credentials only in T3's memory (no Infisical). After a restart T3 cannot read them back, so it issues a new generation for every module (seen: generation 1 → 4 after three image updates). Apps survive (they re-read the file and retry), but every restart is a fleet-wide rotation.
  • Corpus: this is exactly why the design makes Infisical "the commit point". The PoC skipped Infisical; a real build must not.
10. Logto's own app records cannot sit in Logto's chart — FIXED IN POC (H4) · corpus note
  • What happened: if dpoc-aldehyde.lithium's primordial chart held a LogtoApp, its Argo CD app could only be Healthy after Logto runs, and Logto cannot run before its Database (same app) is Ready → the stage waits on itself.
  • PoC fix: Logto's chart has only its Database; the T3 logto controller boot-seeds its own admin app straight into Logto's database.
11. A broken release holds its stage until the health wait times out, which blocks the fix — FIXED IN POC by hand · corpus should change
  • What happened: Logto 1.0.0 could not start (item 8). Its Kargo promotion kept waiting for health (our argocd-update retry window is 15 min, needed for spike A hole 4). Logto 1.0.1 (the fix) was published 2 minutes later but could not promote until the first one ended.
  • PoC fix: aborted the stuck promotion (kargo.akuity.io/abort); 1.0.1 promoted at once.
  • Corpus change: say what aborts a waiting promotion when newer Freight arrives (T3 could do it: "newer Freight for the same stage + current promotion unhealthy > N min → abort"), or keep the health wait short and do the "apps not created yet" retry differently.

All screens