infra_wiki

Built apps

A kthx built app is a repository or archive that kthx builds into a signed artifact and deploys to Targets on the clusters, GCP, Vercel or Cloudflare.

live

A built app is an App that kthx builds from a GitHub repository or an uploaded archive, signs, and deploys. The owner and agents manage them in the console and over MCP.

Concepts#

NounMeaning
AppA source and the Components deployed from it
ComponentA service, website or job in an App
VesselA cluster, GCP project, Vercel team or Cloudflare account, created by OpenTofu
TargetOne runtime on a Vessel, where a Component runs
BuildOne run of a build route. Its Artifact is an image digest or a file tree.
DeployAn Artifact and config applied to a Target
DatastoreA Postgres or Valkey instance for Apps
FunctionA JavaScript fetch handler on Workers or Cloud Run, with no Build or Deploy

Supply chain: Source, Build, Artifact, Deploy

Targets#

Vessels and their Targets

TargetVesselA Deploy creates
kubernetesfolly or offsiteA spindrift-app HelmRelease or an Argo CD Application that installs into app-<app>
cloudrunbluenoseA Cloud Run service or job
staticbluenoseA Firebase Hosting release
vercelVercel teamA prebuilt deployment
cloudflare-pagesCloudflare accountA Pages deployment

A Target's console page lists each missing prerequisite and the OpenTofu code that adds it, which kthx can open as a pull request. Disconnecting a Target stops deploys to it and leaves its workloads running.

Deleting an App deletes its namespace. Removing a static Component spends its Firebase Hosting site id, so a redeploy needs a new App or Component name.

Builds#

A file in each scope of a repository states the scope's kind and build, and it wins over detection. kthx reads kthx.yaml, or spindrift.yaml when a scope has none. Connecting a repository writes kthx.yaml into a scope that has neither. apps/kthx-engine/src/domain/detection/kthx-file.ts holds the schema.

A Build uses the first route, in Settings rank order, whose SLSA (Supply-chain Levels for Software Artifacts) build level meets the Target's minimum, 2 by default. An App can pin one route.

RouteLevelRuns on
github-actions2.github/workflows/kthx-engine-build.yml
cloud-build3Cloud Build
in-cluster1A Job in spindrift-build on offsite. The route's nodeSelector and tolerations put it on hotrod, the sandbox node.
bosun2Bosun, which is parked

Addresses and config#

A Component's reach is none, private or public. Ingress and DNS covers the records and zones. auth: proxy adds oauth2-proxy, which admits only the owner's GitHub login.

<app>.lolwtf.dev shows a status page until a Component serves it. kthx writes the record of an App on a zone apex once, and cannot change or delete it.

When the engine has the KTHX_ENGINE_KTHX_* variables, a name an App mints in the quick sites' zone is reserved for the App in kthx first: when its vanity name is set or its zone changes, and before each Deploy. A name a quick site or another App holds refuses the edit or rejects the Deploy.

Only deleting the App releases names: those its placed Components still mint, and none while a retained workload serves them. A name the App reserved through an earlier edit or a deleted Component stays reserved. Two Apps of the same name with a Component of the same name mint one canonical name, so the second one's Deploys are rejected.

apps/kthx-engine/src/commands/apps/kthx-names.ts holds the rule.

kthx writes config values to Secret Manager in bluenose, and each Target reads them from there (Secrets).

Function env values are write-only, but Cloud Run shows them to bluenose readers. Workers Functions need the Cloudflare token scopes in terraform/network/cloudflare/kthx-engine.tf.

Edit on GitHub

↑↓ move ↵ open esc close