Thu 10 Sep · 17:00 CEST · onlineCommunity Town Hall: the roadmap, the three colours, and a live provisioning demoAgenda and registration →
Package Skill

K8s is a Package Skill built with Colors. It provisions a two-node kubeadm cluster in a deployment-owned DigitalOcean VPC, installs pinned Flannel, DigitalOcean cloud-controller and Flux releases, and reconciles applications from a public Git repository.

Installation
npx skills add getcolors/k8s
K8s ships in all three colours — red, green and blue render byte-identical artifacts from one colors.yml, held to parity on every commit. Its launcher, desired state, validation, dry-run boundary, lifecycle graph, and guarded deletion use the same Colors SDK contracts as the other Package Skills.
Step 01

Read desired state

Agent reads colors.yml. It pins the control-plane and worker shapes, Kubernetes and component versions, network CIDRs, state backend, and GitOps repository.

Step 02

Resolve secrets

DigitalOcean, Cloudflare, and remote-state credentials arrive through COLORS_PAR_*; tokens and kubeconfig never enter tracked or generated files.

Step 03

Dry-run boundary

Builds deterministic OpenTofu and Ansible files, then runs create --dry-run before any provider, node, DNS record, or load balancer is contacted.

Step 04

Bootstrap kubeadm

OpenTofu creates the VPC, firewalls, control plane, and worker. Ansible installs containerd and kubeadm, joins the nodes, and keeps administrative access CIDR-restricted.

Step 05

Reconcile and verify

Flux deploys controllers and applications from Git; the workflow waits for both nodes, DNS, TLS, the DigitalOcean load balancer, and the HTTPS health endpoint.

K8s — CREATE / BUILD DAG
start
k8s-infrastructure
k8s-ansible-local
k8s-ansible-remote
k8s-acceptance

Infrastructure is converged before kubeadm touches either node, and acceptance proves the GitOps application over valid HTTPS. Delete first reloads node addresses from remote state, asks Kubernetes to remove its DigitalOcean load balancer, drops the managed SSH alias, and only then reaches guarded infrastructure destruction.

Package Skill

K3s is a Package Skill built with Colors. It provisions one Hetzner Cloud VPS behind a default-deny firewall, installs pinned K3s and Flux releases, and continuously reconciles a public Git repository without exposing the Kubernetes API.

Installation
npx skills add getcolors/k3s
K3s ships in all three colours — red, green and blue render byte-identical artifacts from one colors.yml, held to parity on every commit. Its launcher, desired state, dry-run boundary, and lifecycle graph use the same Colors SDK contracts in every colour.
Step 01

Read desired state

Agent reads colors.yml. It pins the server shape, K3s and Flux versions, state backend, and public GitOps repository.

Step 02

Resolve secrets

Hetzner, R2, and optional Cloudflare credentials arrive through COLORS_PAR_*; none are rendered under .colors/.

Step 03

Dry-run boundary

Builds OpenTofu and Ansible files, then runs create --dry-run before any provider or host is contacted.

Step 04

Provision securely

OpenTofu creates the VPS and firewall; Ansible installs K3s and keeps API port 6443 private behind SSH.

Step 05

Reconcile GitOps

Flux pulls applications and add-ons from Git. ExternalDNS and cert-manager can converge wildcard DNS and TLS without a kubeconfig in CI.

K3s — CREATE / BUILD DAG
start
k3s-compute
k3s-ansible-local
k3s-ansible-remote

The remote branch installs K3s and Flux and waits for the GitOps repository; the local branch writes the SSH alias. `./green kubectl` then crosses an SSH tunnel instead of publishing port 6443. Delete removes the alias before destroying the firewall and server, and the committed guard refuses accidental destruction.

Package Skill

Umami is a Package Skill built with Colors. It provisions one DigitalOcean droplet running Umami web analytics with colocated PostgreSQL 17 behind Caddy, with restore-verified backups to Cloudflare R2.

Installation
npx skills add getcolors/umami
Umami ships in all three colours — red, green and blue render byte-identical artifacts from one colors.yml, held to parity on every commit. Only Caddy's 80/443 are public; PostgreSQL and Umami's own port stay on the private Compose network.
Step 01

Read desired state

Agent reads colors.yml. It pins every image by tag, the droplet shape and region, DNS, backup schedule and retention, and the state backend. No secret appears in it.

Step 02

Resolve secrets

Credentials arrive through COLORS_PAR_* from a gitignored .envrc.private, and are interpolated into the stack at converge time rather than rendered into .colors/.

Step 03

Dry-run boundary

Builds the OpenTofu and Ansible trees, then runs create --dry-run before contacting any provider or machine.

Step 04

Provision and converge

OpenTofu creates the droplet in the region's default VPC behind a firewall, publishes the Cloudflare record, then Ansible converges Docker Compose and issues TLS. The seeded admin password is rotated during the same run.

Step 05

Prove it works

Acceptance verifies HTTPS with a real certificate, refuses to pass while the seeded credentials still authenticate, reads a synthetic event back out of PostgreSQL, and confirms a fresh backup object in R2.

Umami — CREATE / BUILD DAG
start
infrastructure
dns
ansible
acceptance

Three containers: PostgreSQL, Umami and Caddy. Backups dump PostgreSQL nightly, restore each dump into a scratch database before uploading it, and prune R2 to the same horizon as local disk. `compute-prevent-destroy` refuses accidental deletion.

Package Skill

Rybbit is a Package Skill built with Colors. It provisions one DigitalOcean droplet pairing PostgreSQL 17 for metadata and authentication with ClickHouse for columnar events, plus Redis and Caddy.

Installation
npx skills add getcolors/rybbit
Rybbit ships in all three colours — red, green and blue render byte-identical artifacts from one colors.yml, held to parity on every commit. Only Caddy's 80/443 are public; PostgreSQL, ClickHouse, Redis and the Rybbit backend and client ports stay private.
Step 01

Read desired state

Agent reads colors.yml. It pins every image by tag, the droplet shape and region, DNS, backup schedule and retention, and the state backend. No secret appears in it.

Step 02

Resolve secrets

Credentials arrive through COLORS_PAR_* from a gitignored .envrc.private, and are interpolated into the stack at converge time rather than rendered into .colors/.

Step 03

Dry-run boundary

Builds the OpenTofu and Ansible trees, then runs create --dry-run before contacting any provider or machine.

Step 04

Provision and converge

OpenTofu creates the droplet and firewall and publishes DNS; Ansible then generates the stack's database, cache and auth secrets on the machine, retains them, and converges six containers.

Step 05

Prove it works

Acceptance verifies HTTPS with a real certificate, reads a synthetic pageview back out of ClickHouse, and confirms the backup drill left a fresh object in R2.

Rybbit — CREATE / BUILD DAG
start
infrastructure
dns
ansible
acceptance

Six containers. Backups dump PostgreSQL and take a native ClickHouse `BACKUP` — never a hot copy of the data directory, which races running merges — restore the dump into a scratch database before uploading, and prune R2 alongside local disk.

Package Skill

PostHog is a Package Skill built with Colors. It provisions one DigitalOcean droplet running the PostHog application, ClickHouse with embedded Keeper, Kafka, Temporal, a Rust capture service and a plugin server — the tiers PostHog cannot run without, reduced to a single node.

Installation
npx skills add getcolors/posthog
PostHog ships in all three colours — red, green and blue render byte-identical artifacts from one colors.yml, held to parity on every commit. Only Caddy's 80/443 are public; the ingestion path from capture through Kafka to ClickHouse stays on the private Compose network.
Step 01

Read desired state

Agent reads colors.yml. It pins every image by tag, the droplet shape and region, DNS, backup schedule and retention, and the state backend. No secret appears in it.

Step 02

Resolve secrets

Credentials arrive through COLORS_PAR_* from a gitignored .envrc.private, and are interpolated into the stack at converge time rather than rendered into .colors/.

Step 03

Dry-run boundary

Builds the OpenTofu and Ansible trees, then runs create --dry-run before contacting any provider or machine.

Step 04

Provision and migrate

OpenTofu creates the droplet and DNS; Ansible starts the datastores alone, restores a committed schema checkpoint when it matches the pinned image, and applies PostgreSQL and ClickHouse migrations before any application container starts.

Step 05

Prove ingestion

Acceptance verifies HTTPS with a real certificate, posts a synthetic event and reads it back out of ClickHouse — distinguishing an accepted-but-unstored event from a stored one — and confirms a fresh backup object in R2.

PostHog — CREATE / BUILD DAG
start
infrastructure
dns
ansible
acceptance

Ten containers. The application and plugin server are pinned to one upstream commit because they share a Postgres schema; a committed plain-SQL checkpoint replaces an hour of cold migrations, and is restored only when its stamped commit matches the image.

Package Skill

ClickHouse is a Package Skill built with Colors. It provisions a three-node replicated ClickHouse cluster with a three-member Keeper quorum, plus a separate Metabase and PostgreSQL server, on Hetzner Cloud.

Installation
npx skills add getcolors/clickhouse
ClickHouse ships in all three colours — red, green and blue render byte-identical artifacts from one colors.yml, held to parity on every commit. ClickHouse, Keeper, and Metabase stay closed to the public internet; local dbt and browser traffic cross WireGuard.
Step 01

Read desired state

Agent reads colors.yml. It pins four server shapes, ClickHouse, Metabase, PostgreSQL and dbt versions, private networks, DNS, and the state backend.

Step 02

Resolve secrets

Hetzner, Cloudflare, R2, ClickHouse, and Metabase credentials arrive through COLORS_PAR_*; deployment SSH and WireGuard private keys are generated and retained outside remote state.

Step 03

Dry-run boundary

Builds OpenTofu, Ansible, WireGuard, and dbt files, then runs create --dry-run before contacting any provider or server.

Step 04

Provision privately

OpenTofu creates all four servers in parallel behind a default-deny firewall; split Ansible stages then configure ClickHouse and Metabase concurrently after WireGuard is ready.

Step 05

Prove the data path

Local dbt tests replicated tables, acceptance queries them through Metabase and checks public-port isolation, then zero-change OpenTofu plans prove convergence.

ClickHouse — CREATE / BUILD DAG
start
network
access
node-1
node-2
node-3
metabase
firewall
dns
ansible-render
wireguard
clickhouse-config
metabase-config
dbt
acceptance
drift

The shared firewall exposes only SSH, ICMP, and WireGuard UDP. Acceptance verifies Keeper, replicas, dbt, Metabase, DNS, VPN reachability, and public-port isolation; the drift stage requires every OpenTofu plan to be empty. Delete reverses the graph with parallel DNS/firewall and server teardown, while destroy protection refuses accidents.

Package Skill

Airflow is a Package Skill built with Colors. It provisions one VPS running Apache Airflow with LocalExecutor, host Postgres, continuous WAL-G backups, Caddy authentication and TLS, and a private GitHub repository that deploys DAGs over a confined rsync key.

Installation
npx skills add getcolors/airflow
Airflow ships in all three colours — red, green and blue render byte-identical artifacts from one colors.yml, held to parity by its own three-colour harness. Its launcher, desired state, dry-run boundary, and lifecycle graph use the same Colors SDK contracts as the other Package Skills.
Step 01

Read desired state

Agent reads colors.yml. It pins the server, Airflow and Postgres versions, hostname, DAG repository, and backup policy.

Step 02

Resolve secrets

Provider, database, Airflow, backup, and GitHub credentials arrive through COLORS_PAR_*; none are rendered under .colors/.

Step 03

Dry-run boundary

Builds OpenTofu, Ansible, and repository seed files, then runs create --dry-run before contacting a provider or host.

Step 04

Provision safely

OpenTofu creates compute, SMTP, and DNS; Ansible installs Docker, Postgres, WAL-G, Airflow, Caddy, and the deploy account.

Step 05

Deploy DAGs

A private repository pushes DAGs over rrsync; its write-only key is confined to one directory and has no shell or sudo access.

Airflow — CREATE / BUILD DAG
start
airflow-compute
tofu-smtp
tofu-dns
tofu-smtp-post
airflow-ansible-local
airflow-ansible-remote
airflow-github

GitHub follows the remote stage because seeding the repository immediately triggers its deploy workflow, so the matching public key must already be installed. Delete revokes the credential first, removes the local SSH alias, then tears down SMTP, DNS, and compute; it deliberately keeps the DAG repository and the WAL-G archive.

Package Skill

Rama is a Package Skill built with Colors. It provisions a private single-node Rama cluster on DigitalOcean with ZooKeeper, a Conductor and Supervisor, WireGuard access, and optional Cloudflare DNS and Resend mail.

Installation
npx skills add getcolors/rama
Rama ships in green alone. Its launcher keeps Rama service ports off the public internet and configures the local Rama CLI to reach the cluster through WireGuard.
Step 01

Read desired state

Agent reads colors.yml. It pins the Droplet shape, Rama, ZooKeeper and Java versions, VPN network, optional hostname and mail domain, and state backend.

Step 02

Resolve secrets

DigitalOcean, R2, optional Cloudflare and Resend credentials arrive through COLORS_PAR_*; the Rama license and generated WireGuard client remain outside tracked files and remote state.

Step 03

Dry-run boundary

Builds deterministic OpenTofu and Ansible files, then runs create --dry-run before any provider, server, DNS record, or mail domain is contacted.

Step 04

Provision privately

OpenTofu creates the Droplet and default-deny firewall; Ansible installs WireGuard, ZooKeeper, Rama Conductor and Supervisor, exposing only SSH and the VPN publicly.

Step 05

Verify the cluster

Acceptance checks every service, runs conductorReady and numSupervisors through the local Rama CLI, and proves Rama ports are unreachable from the public internet.

Rama — CREATE / BUILD DAG
start
infrastructure
smtp
dns
smtp-post
ansible
acceptance

DNS and mail stages become no-ops when their providers are disabled. Delete reverses the graph, removing local and remote WireGuard configuration before infrastructure; the committed destroy guard refuses accidental deletion.

Package Skill

Once is a Package Skill built with Colors. It provisions a VPS, configures DNS and outgoing mail, installs Docker, and reconciles declared applications — a self-hosted alternative to Netlify or Vercel that an agent runs end to end.

Installation
npx skills add getcolors/once
Once ships in all three colours — red, green and blue are interchangeable managers of the same OpenTofu state, from one colors.yml.
Step 01

Read desired state

Agent reads colors.yml. Hostnames determine DNS zones and mail domains.

Step 02

Resolve secrets

Env map points to COLORS_PAR_* variables, deferred until runtime.

Step 03

Dry-run boundary

Builds files under .colors/ and runs create --dry-run, touching nothing live.

Step 04

Provision & reconcile

OpenTofu provisions compute/SMTP/DNS; Ansible configures local and remote hosts.

Once — CREATE / BUILD DAG
start
tofu-compute
tofu-smtp
tofu-dns
tofu-smtp-post
ansible-local
ansible-remote
github

Publishing follows the remote stage, not the local one: the deploy keys describe a configured host, so a workstation-side failure does not gate them. Delete reverses the graph — it withdraws the published credentials first, then cleanup, SMTP post and DNS, then SMTP and compute in parallel. Step failures travel as namespaced exit codes, never uncaught exceptions.

Package Skill

Vaultwarden is a Package Skill built with Colors. It deploys the pinned public Vaultwarden image on a Basecamp ONCE server, sends the initial owner invitation, and continuously replicates SQLite to Cloudflare R2 for automatic recovery.

Installation
npx skills add getcolors/vaultwarden
Vaultwarden ships in all three colours — red, green and blue render byte-identical artifacts from one colors.yml, held to parity on every commit. The public image needs no GitHub access; an operator-owned repository can opt into ONCE deployment credentials. Public signup and the steady-state admin endpoint stay disabled.
Step 01

Read desired state

Agent reads colors.yml. It pins the hostname and image, owner email, provider choices, R2 replica, retention, snapshot cadence, and weekly restore-check schedule.

Step 02

Resolve secrets

Compute, DNS, SMTP, remote-state, Litestream R2, and bootstrap credentials arrive through COLORS_PAR_*; GitHub is required only when an operator-owned repository is configured.

Step 03

Dry-run boundary

Builds deterministic OpenTofu and Ansible files, then runs create --dry-run before contacting any provider, server, DNS record, mail domain, or repository.

Step 04

Provision and invite

ONCE provisions the server, DNS, mail, and HTTPS. The container uses its temporary loopback admin endpoint to invite the owner, then removes the token and endpoint from steady state.

Step 05

Replicate and recover

Litestream continuously copies SQLite to R2, restores automatically when local data is absent, and verifies a separate replica restore with SQLite integrity checking every week.

Vaultwarden — CREATE / BUILD DAG
start
tofu-compute
tofu-smtp
tofu-dns
tofu-smtp-post
ansible-local
ansible-remote

This diagram shows the public-image path, which omits the inherited GitHub stage. Setting `vaultwarden-repo` adds credential publication after `ansible-remote`; delete revokes those credentials first. The external R2 replica remains available for recovery and the committed destroy guard refuses accidents.

Package Skill

DBOS is a Package Skill built with Colors. It provisions a production-oriented DigitalOcean server, embeds the pinned DBOS TypeScript SDK in a reference HTTP API, keeps PostgreSQL private, publishes Cloudflare HTTPS, and writes PostgreSQL backups to Cloudflare R2.

Installation
npx skills add getcolors/dbos
DBOS ships in green. Its reference workflow durably sleeps, intentionally retries an activity, safely deduplicates caller-supplied workflow IDs, and resumes after the entire Droplet restarts.
Step 01

Read desired state

Agent reads colors.yml. It pins DBOS and the application image, Amsterdam region, Droplet size, apex hostname, retry policy, retention, PostgreSQL, and backup settings.

Step 02

Resolve secrets

DigitalOcean, Cloudflare, R2, PostgreSQL, and backup credentials arrive only through COLORS_PAR_*; COLORS_PAR_PROFILE is explicitly rejected.

Step 03

Dry-run boundary

Build renders deterministic OpenTofu and Ansible files, and create --dry-run walks the graph without contacting providers or requiring credentials.

Step 04

Provision and deploy

OpenTofu discovers the configured region's default VPC instead of creating one, then provisions the guarded Droplet and DNS before ONCE deploys private PostgreSQL and the DBOS API behind HTTPS.

Step 05

Prove recovery

Acceptance checks HTTPS, completion, activity retry, duplicate IDs, deterministic results, R2 backup upload, and recovery after rebooting the Droplet during a durable delay.

DBOS — CREATE / BUILD DAG
start
tofu-compute
tofu-dns
ansible-local
ansible-remote

Delete removes the managed host configuration and DNS before destroying compute, while preserving the pre-existing default VPC, SSH key, R2 state bucket, and backup objects. The committed prevent-destroy guard requires a separately authorized one-run override.

Package Skill

Walter is another Package Skill built with Colors. It provisions one development machine, records it in ~/.ssh/config so ssh <profile> reaches it, and powers it off and on — so the machine you code on costs nothing while you sleep.

Installation
npx skills add getcolors/walter
Walter ships in green alone. A Package Skill picks the runtime that suits it — the SDK offers three, it does not demand all three.
Step 01

Read desired state

Agent reads colors.yml. profile names the work directory, the state keys, and the ~/.ssh/config alias.

Step 02

Resolve secrets

State-backend keys come from COLORS_PAR_*. OCI authenticates from ~/.oci/config, so no token is written anywhere.

Step 03

Dry-run boundary

Builds files under .colors/ and runs create --dry-run, touching nothing live.

Step 04

Provision

OpenTofu provisions the machine; Ansible writes the ssh alias and confirms it answers.

Step 05

Install, then power

The same colors.yml names nix packages, a login shell and asdf runtimes. stop and start take it from there.

Walter — CREATE / BUILD DAG
start
compute
ansible-local
ansible-remote
Walter — STOP / START
start
power-off
start
power-on
ansible-local

Stop and start never reach OpenTofu. No template declares a power state, so powering the machine down out of band causes no drift — there is nothing to reconcile, because power was never managed. Starting reads the address back from the provider rather than from stored state, which a power cycle does not refresh. Delete reverses the create graph, dropping the managed ssh alias before anything is destroyed.

Package Skill

Restate is a Package Skill built with Colors. It provisions a production-oriented single-node Restate server and TypeScript reference application on DigitalOcean, with private service ports, public TLS, durable workflow recovery, and off-server backups.

Installation
npx skills add getcolors/restate
Restate ships in all three colours — red, green and blue render byte-identical artifacts from one colors.yml, held to parity on every commit. Its acceptance workflow deliberately retries an activity and reboots the complete Droplet during a durable delay before verifying the final result.
Step 01

Read desired state

Agent reads colors.yml. It pins Restate, the TypeScript SDK, Caddy, Droplet sizing, backup policy, hostname, region, and state backend.

Step 02

Resolve secrets

DigitalOcean, Cloudflare, remote-state, and backup credentials arrive through COLORS_PAR_*; no credential or generated .colors/ content enters source control.

Step 03

Dry-run boundary

Builds deterministic OpenTofu, Ansible, Compose, Caddy, and application files, then runs create --dry-run before contacting providers or the server.

Step 04

Provision privately

OpenTofu discovers the regional default VPC, creates the Droplet, firewall, and apex DNS record; Ansible converges Restate, the application, Caddy, and scheduled R2 backups.

Step 05

Prove durability

Acceptance checks HTTPS and duplicate IDs, starts a durable delay, reboots the Droplet, and verifies recovery, two failed activity attempts, attempt-three success, status, and deterministic result.

Restate — CREATE / BUILD DAG
start
infrastructure
dns
ansible
acceptance

Restate ingress, administration, fabric, metrics, and SDK ports remain private. Delete reverses Ansible, DNS, and infrastructure while the committed destroy guard refuses accidents; external backup archives remain available for manual recovery.

Package Skill

Temporal is a Package Skill built with Colors. It provisions one DigitalOcean Droplet running PostgreSQL, all four Temporal Server roles, a TypeScript reference API and worker, and Caddy with public TLS.

Installation
npx skills add getcolors/temporal
Temporal ships in all three colours — red, green and blue render byte-identical artifacts from one colors.yml, held to parity on every commit. The reference workflow uses a durable timer, retries an activity twice, rejects duplicate IDs, and returns a deterministic result after service or whole-Droplet restarts.
Step 01

Read desired state

Agent reads colors.yml. It pins Temporal Server and TypeScript SDK releases, PostgreSQL, Droplet shape, namespace, workflow delay, retry policy, DNS, TLS, backups, and state backend.

Step 02

Resolve secrets

DigitalOcean, Cloudflare, and remote-state credentials arrive through COLORS_PAR_*; PostgreSQL credentials are generated and retained on the server rather than rendered under .colors/.

Step 03

Dry-run boundary

Builds deterministic OpenTofu, Ansible, Docker Compose, and TypeScript application files, then runs create --dry-run before contacting a provider, host, or DNS zone.

Step 04

Provision privately

OpenTofu discovers the Amsterdam region's existing default VPC, creates the guarded Droplet and firewall, and publishes apex DNS; PostgreSQL, Temporal, and administrative ports remain private.

Step 05

Prove durability

Acceptance verifies HTTPS, workflow completion, intentional activity retries, duplicate rejection, deterministic status/results, and recovery when Docker or the entire Droplet restarts during the durable delay.

Temporal — CREATE / BUILD DAG
start
infrastructure
dns
ansible
acceptance

The infrastructure stage discovers rather than creates the regional default VPC. Ansible initializes both Temporal PostgreSQL schemas before starting all server roles, the API and Caddy. Delete stops the stack, removes DNS, then reaches guarded infrastructure destruction; acceptance can separately reboot the whole Droplet mid-workflow.

Package Skill

PostgreSQL HA is a Package Skill built with Colors. It provisions a 3-node PostgreSQL 17 cluster on DigitalOcean, establishes etcd v3 quorum consensus with Patroni leader election, routes clients via local HAProxy, and streams continuous WAL backups to Cloudflare R2.

Installation
npx skills add https://github.com/getcolors/postgres-agy --skill package-postgres-agy-green
PostgreSQL HA ships in green (Babashka / Clojure). It orchestrates Patroni, etcd, HAProxy, and pgBackRest with zero human intervention during failover.
Step 01

Read desired state

Agent reads colors.yml. It pins PostgreSQL 17, Patroni 4.1.5, etcd v3.5, 3 Droplets in AMS3, Cloudflare DNS, and pgBackRest R2 bucket.

Step 02

Resolve secrets

DigitalOcean API tokens, Cloudflare DNS tokens, and Cloudflare R2 S3 credentials arrive through COLORS_PAR_* environment variables.

Step 03

Dry-run boundary

Build renders deterministic OpenTofu and Ansible templates locally; create --dry-run walks the execution DAG without contacting live providers.

Step 04

Provision & cluster

OpenTofu provisions 3 Droplets on the private VPC; Ansible converges etcd v3 quorum, initializes Patroni, configures synchronous replication, and starts HAProxy.

Step 05

Stream & verify PITR

pgBackRest streams WAL archives continuously to Cloudflare R2. Automated restore check systemd timers verify standbys can reconstruct state from R2 without data loss.

PostgreSQL HA — CREATE / BUILD DAG
start
tofu-compute
tofu-dns
ansible-local
cluster
ansible-remote

Delete reverses the DAG, removing HAProxy DNS routing before tearing down etcd consensus and destroying Droplets. Guarded by committed `compute-prevent-destroy: true`.

Package Skill

MySQL HA is a Package Skill built with Colors. It provisions a 3-node MySQL 8.4 Group Replication cluster on DigitalOcean, manages dynamic primary election via an automated Floating VIP daemon, and streams continuous 1-minute binary logs to Cloudflare R2.

Installation
npx skills add https://github.com/getcolors/mysql-agy --skill package-mysql-agy-green
MySQL HA ships in green (Babashka / Clojure). Consensus is maintained natively via MySQL Group Communication System (Paxos) without external key-value stores.
Step 01

Read desired state

Agent reads colors.yml. It pins MySQL 8.4, Group Replication Single-Primary mode, Reserved IP, Cloudflare DNS, and R2 backup settings.

Step 02

Resolve secrets

DigitalOcean API tokens, replication credentials, and Cloudflare R2 keys arrive strictly through COLORS_PAR_* environment variables.

Step 03

Dry-run boundary

Renders all OpenTofu and Ansible files locally; create --dry-run verifies execution DAG and cloud plans without making changes.

Step 04

Provision & form group

OpenTofu allocates 3 Droplets and 1 Floating Reserved IP; Ansible joins the 3 members into a Paxos consensus group and starts the VIP claim daemon.

Step 05

Continuous PITR & drill

Systemd services spool binary logs every 60s to Cloudflare R2 with daily compressed dumps and automated scratch restore drills verifying zero transaction lag.

MySQL HA — CREATE / BUILD DAG
start
tofu-compute
tofu-dns
ansible-local
ansible-remote

Delete releases the Floating Reserved IP and DNS records before destroying compute, guarded by `compute-prevent-destroy: true`.

Package Skill

A second, independent implementation of a 3-node PostgreSQL 17 failover cluster, built by Claude Opus 5 in an isolated benchmark run. Patroni 4.1.5 drives a colocated 3-member etcd; HAProxy runs on all three nodes behind three A records, so a failover writes no DNS and calls no cloud API.

Installation
npx skills add https://github.com/getcolors/postgres-ha --skill package-postgres-ha-green
PostgreSQL HA (Opus 5) ships in green (Babashka / Clojure) and depends only on the Colors SDK — it writes its own DigitalOcean and Cloudflare templates rather than reusing Once.
Step 01

Read desired state

The agent reads colors.yml: PostgreSQL 17, Patroni 4.1.5, etcd 3.5.33 pinned by tarball SHA-256, three Droplets in AMS3, and a pgBackRest repository in Cloudflare R2.

Step 02

Resolve secrets

DigitalOcean, Cloudflare and R2 credentials arrive as COLORS_PAR_* environment variables. Only two database credentials exist, and the package is built not to need a third.

Step 03

Dry-run boundary

build renders OpenTofu and Ansible deterministically with no provider contact; create --dry-run walks the whole DAG without side effects.

Step 04

Provision & cluster

OpenTofu creates three Droplets on the region's default VPC; Ansible forms etcd quorum, bootstraps Patroni with quorum synchronous commit ANY 1, and starts an HAProxy on every node.

Step 05

Archive & prove restore

pgBackRest streams WAL to R2 with archive_command held in Patroni's DCS, so a promoted node keeps archiving. A daily timer restores the newest backup, replays every segment, and fails unless a leader-written heartbeat is under 900s old.

PostgreSQL HA (Opus 5) — CREATE / BUILD DAG
start
infrastructure
dns
ansible-local
cluster
acceptance

Delete reverses the DAG, tearing down the cluster and DNS before destroying compute. Guarded by committed `compute-prevent-destroy: true`.

Package Skill

A second, independent implementation of a 3-node MySQL 8.0 failover cluster, built by Claude Opus 5 in an isolated benchmark run. The three mysqld processes are the Paxos group, so quorum needs no external store, and a DigitalOcean reserved IP follows whichever member reports PRIMARY.

Installation
npx skills add https://github.com/getcolors/mysql-ha --skill package-mysql-ha-green
MySQL HA (Opus 5) ships in green (Babashka / Clojure) and depends only on the Colors SDK — it writes its own DigitalOcean and Cloudflare templates rather than reusing Once.
Step 01

Read desired state

The agent reads colors.yml: MySQL 8.0, a fixed group UUID, three Droplets in AMS3, Cloudflare DNS, and an R2 bucket for dumps and binary logs.

Step 02

Resolve secrets

DigitalOcean, Cloudflare and R2 credentials arrive as COLORS_PAR_* environment variables. MySQL caps replication passwords at 32 characters, so the replication account derives its own deterministically rather than requiring a third secret.

Step 03

Dry-run boundary

build renders OpenTofu and Ansible deterministically with no provider contact; create --dry-run walks the whole DAG without side effects.

Step 04

Provision & cluster

OpenTofu creates three Droplets and a reserved IP; Ansible bootstraps Group Replication in single-primary mode, with the group port never leaving the VPC.

Step 05

Archive & prove restore

Every ONLINE member spools binary logs to R2 each minute, so any one member is a complete source and the archiver needs no leader election. A daily scratch mysqld replays them and asserts it recovered past the snapshot.

MySQL HA (Opus 5) — CREATE / BUILD DAG
start
infrastructure
dns
base
cluster
backup
health

Delete releases the reserved IP and DNS records before destroying compute, guarded by committed `compute-prevent-destroy: true`.

Package Skill

WaveHouse is a Package Skill built with Colors. It provisions a public analytics demo on Vultr — ClickHouse, the WaveHouse real-time gateway, and the project's live GitHub stats dashboard — behind Caddy TLS and Cloudflare, with history backfilled from the GitHub API and a poller streaming new events over SSE.

Installation
npx skills add getcolors/wavehouse
WaveHouse ships in all three colours — red, green and blue render byte-identical artifacts from one colors.yml, held to parity on every commit. The dashboard is the upstream project's own page served same-origin with the /v1 API, so the browser SDK needs no configuration; see it live at [stats.bigconfig.space](https://stats.bigconfig.space).
Step 01

Read desired state

Agent reads colors.yml. It names the dashboard host, the tracked owner/name repository, poll interval, container images, and the Vultr and state-backend boundary.

Step 02

Resolve secrets

Vultr, Cloudflare, remote-state, and a read-only GitHub token arrive through COLORS_PAR_*; the gateway's operator key is generated on the server and never leaves it.

Step 03

Dry-run boundary

Builds deterministic OpenTofu, Ansible, Compose, Caddy, schema, and pipe files, then runs create --dry-run before contacting providers or the server.

Step 04

Provision and backfill

OpenTofu creates the instance, firewall, and proxied DNS record; Ansible converges the stack, registers 19 public pipes, backfills GitHub history, and starts the 60-second poller.

Step 05

Prove it is live

Acceptance checks public HTTPS gateway health, the served dashboard assets, and that gh_summary reports backfilled events before create is called done.

WaveHouse — CREATE / BUILD DAG
start
infrastructure
dns
ansible
acceptance

Only Caddy 80/443 and key-only SSH are public; ingest and admin need the server-held operator key while browsers stay anonymous and read-only. Delete reverses Ansible, DNS, and infrastructure while the committed destroy guard refuses accidents.

Package Skill

GitHub DWH is a Blue Package Skill built with Colors. It provisions a single-host warehouse for everything a GitHub organization credential can see — dlt extracts to ClickHouse, dbt builds tested marts, Lightdash serves the dashboards, and a PocketBase control plane schedules and records whole workflow runs behind Caddy TLS on Vultr.

Installation
npx skills add getcolors/github-dwh
GitHub DWH ships in blue alone. PocketBase stores schedules and whole-run history only; Blue owns workflow routing, systemd owns process supervision, and journald owns full logs.
Step 01

Read desired state

Agent reads colors.yml. It names the GitHub organization and resources, the control-plane and analytics hosts, ClickHouse databases, the Lightdash R2 bucket, the dispatch calendar, and the Vultr and state-backend boundary.

Step 02

Resolve secrets

Vultr, Cloudflare, remote-state, GitHub, ClickHouse, and Lightdash credentials arrive through COLORS_PAR_*; the package refuses a COLORS_PAR_PROFILE overlay because profile keys the shared remote state.

Step 03

Dry-run boundary

Builds deterministic OpenTofu, Ansible, Compose, and dbt files, then runs create --dry-run before contacting providers or the server.

Step 04

Provision and converge

OpenTofu creates the instance, firewall, and DNS records with state in R2; Ansible converges ClickHouse, PocketBase, Lightdash, Caddy, and the systemd dispatcher, then converges the Lightdash organization, project, and dashboard.

Step 05

Run the warehouse

Each scheduled or manual PocketBase run is one ./blue run: dlt extracts, dbt builds and tests the marts, and Lightdash resynchronizes — with full logs in journald.

GitHub DWH — RUN DAG
start
dlt
dbt-run
dbt-test
lightdash

Create converges infrastructure and services as its own DAG (`start` → `tofu` → `ansible`); a failed load is retried only as a new complete run. Delete reverses Ansible and infrastructure while the committed destroy guard refuses accidents.

Package Skill

ClickStack is a Package Skill built with Colors. It provisions the HyperDX observability stack on a single Vultr instance — ClickHouse for telemetry, MongoDB for application state, the HyperDX OpenTelemetry collector, and the HyperDX UI — behind Caddy TLS and Cloudflare, with logs, traces, and metrics ingested over OTLP on the same host that serves the dashboard.

Installation
npx skills add getcolors/clickstack
ClickStack ships in all three colours — red, green and blue render byte-identical artifacts from one colors.yml, held to parity on every commit. One hostname carries both halves: the UI and OTLP/HTTP ingestion share port 443, so an exporter needs no endpoint beyond https://<host> and 4317/4318 are never exposed.
Step 01

Read desired state

Agent reads colors.yml. It names the public host, the initial team's admin email, the five container images, and the Vultr and state-backend boundary. It carries no key material and no secret.

Step 02

Own the machine keypair

With no vultr-ssh-keys in desired state the package generates ~/.ssh/<profile>, registers it as the Vultr account key named for the profile, and removes it last on delete — the workspace SSH keypair standard, not a bespoke rule.

Step 03

Dry-run boundary

Builds deterministic OpenTofu, Ansible, Compose, and Caddy files, then runs create --dry-run before contacting providers or the server. Build and dry-run need no credentials and never read ~/.ssh.

Step 04

Provision and converge

OpenTofu creates the instance, a firewall open only on 22/80/443, and a proxied Cloudflare record; Ansible converges the Compose stack and creates the initial HyperDX team — until one exists the collector binds no OTLP receivers at all.

Step 05

Prove it ingests

Acceptance sends one OTLP log over public HTTPS and reads the row back out of ClickHouse, so create is called done only when telemetry actually lands.

ClickStack — CREATE / BUILD DAG
start
infrastructure
dns
ansible
acceptance

The ingestion key is the team's own `apiKey`, minted by the application and therefore unknowable in advance; convergence reads it back rather than inventing one. Delete reverses Ansible, DNS, and infrastructure and drops the keypair only after the compute destroy succeeded, while the committed destroy guard refuses accidents.

Package Skill

SigNoz is a Package Skill built with Colors. It provisions the SigNoz observability stack on a single Vultr instance — ClickHouse and ClickHouse Keeper for telemetry, a Postgres metastore for dashboards and alert rules, the schema migrator, the SigNoz application, and the signoz-otel-collector ingester — behind Caddy TLS and Cloudflare, with traces, logs, and metrics arriving over OTLP on the same host that serves the UI.

Installation
npx skills add getcolors/signoz
SigNoz ships in all three colours — red, green and blue render byte-identical artifacts from one colors.yml, held to parity on every commit. One hostname carries both halves: the UI and OTLP/HTTP ingestion share port 443, so an exporter needs no endpoint beyond https://<host> and 4317/4318 never leave loopback.
Step 01

Read desired state

Agent reads colors.yml. It names the public host, the root account, the six container images, the nightly metastore backup, and the Vultr and state-backend boundary. It carries no key material and no secret.

Step 02

Own the machine keypair

With no vultr-ssh-keys in desired state the package generates ~/.ssh/<profile>, registers it as the Vultr account key named for the profile, writes the matching ~/.ssh/config block so ssh <profile> works, and removes the key last on delete — the workspace SSH keypair and config standards, not bespoke rules.

Step 03

Dry-run boundary

Builds deterministic OpenTofu, Ansible, Compose, and Caddy files, then runs create --dry-run before contacting providers or the server. Build and dry-run need no credentials and never read ~/.ssh.

Step 04

Provision and converge

OpenTofu creates the instance, a firewall open only on 22/80/443, and a proxied Cloudflare record before Caddy asks Let's Encrypt for a certificate; Ansible then converges the Compose stack and mints the OTLP bearer token on the server, because SigNoz community edition has no ingestion keys of its own.

Step 05

Prove it is closed

The end-to-end ingest proof runs on the server where the token lives. From outside, acceptance requires the UI over HTTPS, a healthy API, and an unauthenticated OTLP write that comes back 401 — an endpoint that accepted it would be an open write path into ClickHouse.

SigNoz — CREATE / BUILD DAG
start
infrastructure
ssh-config
dns
ansible
acceptance

Delete is not the create order reversed twice over: the `~/.ssh/config` block goes before the compute destroy, while the keypair goes after it — a stale block is harmless, a key removed early locks you out of a machine that still exists. The committed destroy guard refuses accidents either way.

Package Skill

NetBird is a Package Skill built with Colors. It provisions a self-hosted NetBird control plane on a single Vultr instance — Traefik, the combined `netbird-server` carrying management, signal, relay and STUN, the dashboard, and Authentik with its Postgres and Redis — behind Cloudflare and Let's Encrypt, with SSO through Authentik and encrypted nightly backups to R2.

Installation
npx skills add getcolors/netbird
NetBird ships in all three colours — red, green and blue render byte-identical artifacts from one colors.yml, held to parity on every commit. Management, signal, relay and STUN are one process multiplexed behind Traefik on 443, so the firewall opens 22, 80, 443 and a single UDP port — and nothing else.
Step 01

Read desired state

Agent reads colors.yml. It names the two public hosts, the local break-glass owner, Authentik's first administrator, the seven container images, the nightly encrypted backup, and the Vultr and state-backend boundary. It carries no key material and no secret.

Step 02

Own the machine keypair

With no vultr-ssh-keys in desired state the package generates ~/.ssh/<profile>, registers it as the Vultr account key named for the profile, writes the matching ~/.ssh/config block so ssh <profile> works, and removes the key last on delete — the workspace SSH keypair and config standards, not bespoke rules.

Step 03

Dry-run boundary

Builds deterministic OpenTofu, Ansible, Compose and Traefik files, then runs create --dry-run before contacting providers or the server. Build and dry-run need no credentials and never read ~/.ssh.

Step 04

Provision and converge

OpenTofu creates the instance, a firewall open only on 22/80/443 and one UDP port, and two unproxied Cloudflare records — proxying would break both STUN and the TLS-ALPN-01 challenge. Ansible then converges the Compose stack and generates every remaining secret on the host, where it stays.

Step 05

Sign in without a browser

Convergence drives the real OAuth2 flow through Authentik's flow-executor API and creates the federated account itself, so there is no wizard and no GUI step. Acceptance enrols two throwaway peers on isolated networks, proves traffic flows over the relay, validates both certificates through the system trust store, and reads the served dashboard JavaScript to prove it was configured rather than merely answering 200.

NetBird — CREATE / BUILD DAG
start
infrastructure
ssh-config
dns
ansible
acceptance

DNS sits before convergence because Traefik asks Let's Encrypt for a certificate the moment it starts and TLS-ALPN-01 only succeeds once the names resolve. Delete reverses that, except twice: the `~/.ssh/config` block goes before the compute destroy while the keypair goes after it, and a final encrypted backup is taken before anything is torn down. The committed destroy guard refuses accidents either way.

Package Skill

Agent Network is a Package Skill built with Colors. It provisions a minimal NetBird Agent Network demo on a single Vultr instance — Traefik, the combined `netbird-server`, the dashboard in agent-network view, the private reverse proxy — and an agent container running headless Claude Code on an internal Docker network with no internet route. The agent holds no API key: its only path to an LLM is the generated tunnel-only endpoint, where every request carries its peer identity, passes a model allowlist and per-day budget caps, and lands attributed in the access log.

Installation
npx skills add getcolors/agent-network
Agent Network ships in all three colours — red, green and blue render byte-identical artifacts from one colors.yml, held to parity on every commit. The isolation is the demo: an internal Docker network doubled by port-scoped DOCKER-USER rules, with acceptance proving the negative space — raw-TCP probes that must fail beside a control probe that must succeed — after a real Docker restart and a real reboot.
Step 01

Read desired state

Agent reads colors.yml. It names the public host and its wildcard, the claimed models with their prices, the guardrail allowlist, the per-day policy caps and the account-wide ceiling, the two Docker subnets, and every image by tag and digest. It carries no key material and no secret.

Step 02

Own the machine keypair

With no vultr-ssh-keys in desired state the package generates ~/.ssh/<profile>, registers it as the Vultr account key named for the profile, writes the matching ~/.ssh/config block so ssh <profile> works, and removes the key last on delete — the workspace SSH keypair and config standards, not bespoke rules.

Step 03

Dry-run boundary

Builds deterministic OpenTofu, Ansible, Compose and Traefik files, then runs create --dry-run before contacting providers or the server. Build and dry-run need no credentials and never read ~/.ssh.

Step 04

Provision and converge

OpenTofu creates the instance, a firewall open only on 22/80/443 and one UDP port, and two unproxied Cloudflare records — the name and its wildcard, because the endpoint label is minted at bootstrap and nothing knows it earlier. Ansible converges the stack, issues the wildcard certificate over DNS-01, and reconciles the control plane headlessly: admin account, endpoint, provider, guardrail, policy, global limit, and the agent's single-use setup key on tmpfs.

Step 05

Prove the claim

Acceptance is the demo: the agent cannot reach the internet but its keyless call traverses the tunnel; a claimed-but-disallowed model is denied by the guardrail and an unclaimed one by routing, both at zero upstream cost; headless Claude Code rides the same governed path; every access-log entry carries the enrolled peer id; and an outside caller gets exactly the pre-identity 403. A deliberately fake provider key is a supported mode — the relayed upstream 401 proves the whole path with nothing billable.

Agent Network — CREATE / BUILD DAG
start
infrastructure
ssh-config
dns
ansible
acceptance

DNS sits before convergence because both certificate paths need resolvable names — Traefik's TLS-ALPN-01 for the base host and lego's DNS-01 for the wildcard the endpoint lives under. Delete reverses that with the standard split: the `~/.ssh/config` block goes before the compute destroy while the keypair goes after it. No backups, deliberately — the deployment is disposable, and a later create regenerates the endpoint hostname and every peer identity.

Package Skill

Agent Network K8s is a Package Skill built with Colors. It provisions the NetBird Agent Network demo on a Vultr Kubernetes Engine cluster — Traefik behind a TCP load balancer, the combined `netbird-server` on a CSI volume, the dashboard in agent-network view, the private reverse proxy — and a two-pod application: the NetBird client in netstack/SOCKS5 mode (userspace WireGuard — no TUN device, no capabilities) and an agent pod running headless Claude Code whose only network egress, enforced by a default-deny NetworkPolicy, is that SOCKS5 listener. The agent holds no API key, no ServiceAccount token, and no DNS: its one road to an LLM is the tunnel-only endpoint, where every request carries its peer identity, passes a model allowlist and per-day budget caps, and lands attributed in the access log.

Installation
npx skills add getcolors/agent-network-k8s
Agent Network K8s ships in all three colours — red, green and blue render byte-identical artifacts from one colors.yml, held to parity by its own three-colour harness. The isolation claim is probed from both sides of the SOCKS5 listener — raw-TCP probes around it and CONNECT probes through it, each paired with a control that must succeed — under restricted Pod Security, and re-proven by a five-disruption suite that ends with a node drain.
Step 01

Read desired state

Agent reads colors.yml. It names the public host and its wildcard, the claimed models with their prices, the guardrail allowlist, the per-day policy caps and the account-wide ceiling, the VKE version and node pool, and every image by tag and digest — the NetBird release train, the kaniko builder, and the agent image's pinned inputs. It carries no key material and no secret.

Step 02

Dry-run boundary

Builds deterministic OpenTofu, Kubernetes manifests, the NetworkPolicy matrix, and every converge script, then runs create --dry-run before contacting providers or the cluster. Build and dry-run need no credentials; the pinned VKE version is checked against the live supported list while failing is still free.

Step 03

Provision and converge

OpenTofu creates the VKE cluster and a deployment-owned container registry; kubectl converges the gateway with create-once cluster secrets and a proxy token minted in-cluster; kaniko builds the agent image from a streamed, content-addressed context, and the deploy consumes only the digest read back from the registry. DNS goes to the load balancer, and one lego DNS-01 order carries both SANs — the base name and its wildcard.

Step 04

Enroll the two-pod application

The control plane is reconciled headlessly — admin account, endpoint, provider, guardrail, policy, global limit — and the client enrolls with a single-use setup key streamed over exec stdin into memory-backed storage, never a Kubernetes Secret. The reverse proxy is an embedded peer invisible to the peers API, so its overlay address is read from the enrolled client's own network map and reconciled whenever a restart mints a new one.

Step 05

Prove the claim

Acceptance probes the negative space from both sides of the listener: the agent reaches nothing directly, and CONNECTs through the SOCKS5 pod reach only the proxy's overlay address — public names, the metadata endpoint, and the API server all refuse. Both denial classes land at zero upstream cost, an outside caller gets exactly the pre-identity 403, limits read back as desired state says, and the whole claim is re-proven after pod deletes, gateway restarts, and a node drain. A deliberately fake provider key is a supported mode — the relayed upstream 401 proves the path with nothing billable.

Agent Network K8s — CREATE / BUILD DAG
start
infrastructure
deploy
dns
certificate
bootstrap
agent
acceptance

Deploy applies the edge and the proxy but deliberately does not await them — both mount the TLS Secret the certificate stage issues after DNS points at the load balancer — and their readiness is claimed only once it exists. Delete tears down in-cluster first (workloads, CSI volumes, the load balancer, each confirmed absent at the provider) because those are Kubernetes-managed and invisible to the infrastructure state. No backups, deliberately — the deployment is disposable, and a later create regenerates the endpoint hostname and every peer identity.

Package Skill

Agent Network DOKS is a Package Skill built with Colors. It provisions the NetBird Agent Network demo on a DigitalOcean Kubernetes cluster — Traefik behind a TCP-mode regional Load Balancer, the combined `netbird-server` on a CSI volume, the dashboard in agent-network view, the private reverse proxy — and the two-pod application: the NetBird client in netstack/SOCKS5 mode (userspace WireGuard — no TUN device, no capabilities) and an agent pod running headless Claude Code whose only network egress, enforced by a default-deny NetworkPolicy, is that SOCKS5 listener. The agent holds no API key, no ServiceAccount token, and no DNS: its one road to an LLM is the tunnel-only endpoint, where every request carries its peer identity, passes a model allowlist and per-day budget caps, and lands attributed in the access log.

Installation
npx skills add getcolors/agent-network-doks
Agent Network DOKS ships in all three colours — red, green and blue render byte-identical artifacts from one colors.yml, held to parity by its own three-colour harness across both state backends. The isolation claim is probed from both sides of the SOCKS5 listener under restricted Pod Security, and a Cilium canary proves NetworkPolicy enforcement on the actual cluster before any secret enters it.
Step 01

Read desired state

Agent reads colors.yml. It names the public host and its wildcard, the claimed models with their prices, the guardrail allowlist, the per-day policy caps and the account-wide ceiling, the DOKS version slug and node pool, and every image by tag and digest. The cluster subnets appear nowhere — they are outputs, read back from the API. It carries no key material and no secret.

Step 02

Dry-run boundary

Builds deterministic OpenTofu, Kubernetes manifests, the NetworkPolicy matrix, and every converge script, then runs create --dry-run before contacting providers or the cluster. Build and dry-run need no credentials; the pinned DOKS version slug is checked against the live supported list while failing is still free.

Step 03

Provision and converge

OpenTofu creates the DOKS cluster and the container registry — created and profile-named, or adopted by name behind a tier-aware capacity preflight — with asymmetric rotated credentials: the write credential exists only while kaniko builds, and the read-only pull credential is re-applied each converge. kubectl converges the gateway, kaniko builds the agent image in-cluster from a streamed, content-addressed context, and the deploy consumes only the digest read back from the registry. DNS goes to the load balancer, and one lego DNS-01 order carries both SANs — the base name and its wildcard.

Step 04

Enroll the two-pod application

The control plane is reconciled headlessly — admin account, endpoint, provider, guardrail, policy, global limit — and the client enrolls with a single-use setup key streamed over exec stdin into memory-backed storage, never a Kubernetes Secret. The reverse proxy is an embedded peer invisible to the peers API, so its overlay address is read from the enrolled client's own network map and reconciled whenever a restart mints a new one.

Step 05

Prove the claim

Acceptance probes the negative space from both sides of the listener: the agent reaches nothing directly, and CONNECTs through the SOCKS5 pod reach only the proxy's overlay address. The load-balancer firewall is verified through the DigitalOcean API — an open deployment cannot prove denial by probing. Both denial classes land at zero upstream cost, an outside caller gets exactly the pre-identity 403, and the whole claim is re-proven after pod deletes, gateway restarts, and a node drain. A deliberately fake provider key is a supported mode — the relayed upstream 401 proves the path with nothing billable.

Agent Network DOKS — CREATE / BUILD DAG
start
infrastructure
deploy
dns
certificate
bootstrap
agent
acceptance

Deploy applies the edge and the proxy but deliberately does not await them — both mount the TLS Secret the certificate stage issues after DNS points at the load balancer — and their readiness is claimed only once it exists. Delete tears down in-cluster first (workloads, CSI volumes, the load balancer, each confirmed absent at the provider) because those are Kubernetes-managed and invisible to the infrastructure state; an adopted registry survives, with exactly the deployment's own repository deleted. No backups, deliberately — the deployment is disposable, and a later create regenerates the endpoint hostname and every peer identity.

Package Skill

Neon is a Package Skill built with Colors. It provisions self-hosted Neon — Postgres with storage and compute separated — on a single Vultr instance: the storage broker, the pageserver, one safekeeper, and a Postgres 17 compute node under compute_ctl, with pageserver layers and safekeeper WAL uploaded to Cloudflare R2 under the deployment's own prefix. The R2 prefix plus the tenant and timeline ids in colors.yml are the database: a rebuilt host re-attaches the same identities and rehydrates from R2.

Installation
npx skills add getcolors/neon
Neon ships in all three colours — red, green and blue render byte-identical artifacts from one colors.yml, held to parity on every commit. Nothing is published beyond loopback: the firewall opens 22 only, and the supported client path is an SSH tunnel through the ~/.ssh/config alias the package writes.
Step 01

Read desired state

Agent reads colors.yml. It names the two digest-pinned images, the Postgres major, the 32-hex tenant and timeline identities, the application database and role, the R2 endpoint and bucket, and the Vultr and state-backend boundary. It carries no key material and no secret.

Step 02

Own the machine keypair

With no vultr-ssh-keys in desired state the package generates ~/.ssh/<profile>, registers it as the Vultr account key named for the profile, and writes the matching ~/.ssh/config block — the alias the converge, the client tunnel, and the acceptance probe all ride.

Step 03

Dry-run boundary

Builds deterministic OpenTofu, Ansible, Compose, and compute-spec files, then runs create --dry-run before contacting providers or the server. Build and dry-run need no credentials and never read ~/.ssh.

Step 04

Provision and converge

OpenTofu creates the instance and a firewall open only on 22; Ansible converges the storage tier, reconciles the tenant and timeline against R2 behind two-phase ownership markers and a monotonic generation counter, mints SCRAM credentials on the host, and only then starts the compute node — recreate-only by doctrine.

Step 05

Prove it works

Acceptance asks the system what it has: a SQL round-trip, a wrong password refused, a passwordless connection refused, privilege escalation refused, a new WAL segment in R2 beyond a pre-switch baseline — and, from the workstation, the same probe through the SSH tunnel itself.

Neon — CREATE / BUILD DAG
start
infrastructure
ssh-config
ansible
acceptance

There is no dns stage on purpose: nothing in this package is reachable by name. Delete removes the `~/.ssh/config` block before the compute destroy and the keypair after it — and leaves the R2 data in place, because that prefix is the database, not a byproduct.

Package Skill

n8n is a Package Skill built with Colors. It provisions n8n 2.36.9 on a single Vultr instance — the n8n server, an external task runner isolating Code nodes, and Caddy terminating TLS — backed not by a colocated Postgres but by a colocated self-hosted Neon, so the durable copy of every workflow, credential and execution lives in Cloudflare R2 rather than on the instance's disk. Seven containers, one Compose project, and only the proxy publishes beyond loopback.

Installation
npx skills add getcolors/n8n
n8n ships in green. The storage tier is not reimplemented: this package SHA-pins getcolors/neon and renders that package's templates straight off the classpath, so no copy of the storage tier exists here to drift — n8n's services arrive as a Compose override installed beside the upstream file, which is what lets every unchanged upstream command operate on the one merged project.
Step 01

Read desired state

Agent reads colors.yml. It carries the digest-pinned n8n, runner, Caddy and Neon images, the 32-hex tenant and timeline identities, the public hostname, retention and concurrency bounds, and declared soak thresholds. It holds no key material — and it speaks the storage tier's key vocabulary, because those templates are rendered from a pin rather than copied.

Step 02

Refuse what fails later

Validation reports every problem at once and encodes traps as rules: a runner image whose version differs from the n8n image, the deprecated WEBHOOK_URL spelling, binary data left in memory, an unbounded concurrency limit, and Cloudflare-only ingress without a proxied record — which would otherwise pass the converge and fail hours later with no certificate.

Step 03

Dry-run boundary

Builds deterministic OpenTofu, Ansible, Compose and Caddy files, then walks the DAG with every side effect skipped. Build and dry-run need no credentials, and an offline --syntax-check over the rendered playbooks catches the whole class of failures that only appear at Ansible load time.

Step 04

Provision and converge

OpenTofu creates the instance, a DNS record, and a firewall whose HTTP rules resolve to Cloudflare's published ranges; Ansible converges the storage tier through the imported upstream play, then n8n's own — and claims the owner account over the internal network before the public name resolves, closing the window in which an unauthenticated setup screen hands the instance to whoever finds it first.

Step 05

Prove it works

Seventeen gates ask the system what it has: a workflow created through the public API and read back out of Neon, a new WAL segment in R2 beyond a pre-switch baseline, liveness and readiness separately, the generated webhook URL exactly, and a Code node that actually executes on the external runner — because a runner reports connected long before it has run a task.

n8n — CREATE / BUILD DAG
start
infrastructure
dns
ssh-config
ansible
acceptance

`dns` comes before the converge, not after: Caddy provisions its certificate over ACME on first start, and the HTTP-01 challenge needs the name to already resolve. Delete reverses it — the record goes before the compute destroy, so nothing resolves to an address that has stopped answering.

Package Skill

AutoMQ is a Package Skill built with Colors. It provisions three AutoMQ 1.7.4 nodes on Vultr — the Apache Kafka 3.9.1 wire protocol, both KRaft roles on every node — with Cloudflare R2 as the storage tier rather than replicated local disks. A produce is acknowledged once the record is in R2, which is why every topic is replication factor 1 and why losing a broker loses no bytes. The three nodes buy the controller quorum, partition failover and throughput; they do not buy copies.

Installation
npx skills add getcolors/automq
AutoMQ ships in all three colours — red, green and blue render byte-identical artifacts from one colors.yml, held to parity on every commit. The public endpoint on 9092 is SASL_SSL with SCRAM-SHA-512 and a StandardAuthorizer ACL set, because a port facing the internet is not gated by a firewall and authentication is not authorization. The controller quorum and inter-broker replication never leave a Vultr VPC.
Step 01

Read desired state

Agent reads colors.yml. It names the digest-pinned image, the node count, the cluster id that is also the object namespace, the bootstrap and broker hostnames, the two R2 buckets, and the VPC and firewall boundary. It carries no key material and no secret.

Step 02

Adopt storage, never create it

AutoMQ writes hash-prefixed keys at the bucket root and supports no path prefix, so a bucket belongs to one cluster outright. Adoption proves emptiness by paginating the whole bucket, claims ownership with a conditional create, and carries one transaction id across both buckets — so a half-adopted pair resumes and a mismatched one fails.

Step 03

Dry-run boundary

Builds deterministic OpenTofu, Cloudflare records, Ansible, Compose and broker configuration, then runs create --dry-run before contacting providers. Build and dry-run need no credentials and never read ~/.ssh.

Step 04

Provision and converge

OpenTofu creates the VPC, the firewall and three instances; Ansible opens the host firewall the image ships enabled, issues one certificate from node 0 alone, formats the quorum with identical SCRAM bootstrap records, and starts the brokers.

Step 05

Prove it works

Six gates on the hosts and seven from the workstation, including a failover targeted at a partition because the killed broker leads it — a generic round trip over six partitions can pass without ever touching the broker it killed.

AutoMQ — CREATE / BUILD DAG
start
infrastructure
ssh-config
dns
ansible
acceptance

DNS comes before convergence because every broker advertises a name that must already resolve, and the certificate is issued for those names during the play. Delete unwinds the other way and stops at the storage: the buckets hold the cluster’s data, so an accidental delete stays recoverable.

Package Skill

Langfuse is a Package Skill built with Colors. It provisions Langfuse v4 across six Vultr machines in one VPC — a self-hosted Neon storage tier for Postgres, a Redis host, three ClickHouse replicas with their own Keeper quorum, and the application host running langfuse-web, langfuse-worker and Caddy behind Cloudflare — with Cloudflare R2 holding raw events, media, Neon's layers and WAL, and the backups. Langfuse's own guidance is one Docker Compose host or Kubernetes; this is the shape in between, and every separation claim is a gate.

Installation
npx skills add getcolors/langfuse
Langfuse ships in green, red, and blue — three implementations rendering byte-identical output, checked by scripts/parity.sh on both fixtures. The storage tier is rendered from a SHA pin on getcolors/neon, never copied; the ClickHouse cluster templates are the package's own, derived from getcolors/clickhouse. Each role has its own firewall group — a Vultr group filters the private interface too — and every east-west rule names the peer's /32.
Step 01

Read desired state

Agent reads colors.yml. It carries digest-pinned Langfuse, Redis, Caddy and Neon images, an exact ClickHouse apt version, the VPC subnet, four plans, the public hostname, headless-init identities, two R2 buckets and three backup cadences with per-store freshness thresholds. It holds no key material, and three application secrets — ENCRYPTION_KEY, SALT, the initial password — are the operator's to hold because a backup is readable only with them.

Step 02

Refuse what fails later

Validation reports every problem at once: a ClickHouse version below 25.12 that would pass the converge and fail the first v4 migration, a cluster not named default that Langfuse cannot migrate ON CLUSTER, an S3 prefix without its trailing slash, a backup bucket that is also a live-data bucket, and any R2 credential reaching state and a host alike unless desired state records that choice.

Step 03

Dry-run boundary

Builds deterministic OpenTofu, Ansible, Compose and Caddy files for all six hosts, with placeholder addresses inside the subnet, then walks the DAG with every side effect skipped. Build and dry-run need no credentials, and an offline --syntax-check over the three rendered playbooks catches load-time failures in a second.

Step 04

Provision and converge

OpenTofu creates the VPC, four role-scoped firewall groups, six instances and a proxied DNS record; Ansible converges the storage tier through the imported neon play, the three replicas with secrets generated on node 0 and propagated as facts, Redis, then the app host — whose environment is assembled from the passwords the other hosts generated, read where they live.

Step 05

Prove it works

Gates ask the system what it has: raw TCP to every dependency and a refusal on Keeper, UTC on both databases, a trace read back through the public API and found on node 0 and the last replica, a new raw-event object in R2, a media file back with the same sha256, five refusals, 200 traces under the timeout — and rehearse restores both stores, boots the pinned image against them, drills a replica loss and a Redis restart, then writes a second marker.

Langfuse — CREATE / BUILD DAG
start
infrastructure
dns
ssh-config
ansible
acceptance

`ansible` is one inventory of six hosts in four groups and seven plays in dependency order: common hardening, the Neon overlay, the imported neon play, ClickHouse, Redis, the app, the backups. `.colors-ready` lands only after the gates; `.colors-recovery-verified` only after the rehearsal — automation can tell the two claims apart.

Find infrastructure your agent can operate.

Browse the PR-curated Skills Catalog by platform, provider, or runtime.

View the Catalog