R2D2-MERIDIAN/deploy/AGENTS.md
Joshua Belke c5afeed1c1
Some checks failed
helm chart / lint + unittest + render matrix (push) Has been cancelled
helm chart / install on kind (gated) (push) Has been cancelled
helm chart / publish chart to GHCR (push) Has been cancelled
Meridian Harness / Build (aarch64-unknown-linux-musl) (push) Has been cancelled
Meridian Harness / Build (x86_64-unknown-linux-musl) (push) Has been cancelled
Meridian Harness / Publish rolling release (push) Has been cancelled
Meridian Harness / Publish tagged release (push) Has been cancelled
CI / Detect Changed Paths (push) Has been cancelled
CI / Dead Token Reference Guard (push) Has been cancelled
Docker image / Build (linux/amd64) (push) Has been cancelled
Docker image / Build (linux/arm64) (push) Has been cancelled
Docker image / Build public push gateway (linux/amd64) (push) Has been cancelled
Docker image / Build public push gateway (linux/arm64) (push) Has been cancelled
CI / Rust Lint (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Isolated DB Gate (push) Has been cancelled
CI / Desktop Core (push) Has been cancelled
CI / Desktop Smoke E2E (1) (push) Has been cancelled
CI / Desktop Smoke E2E (2) (push) Has been cancelled
CI / Desktop Smoke E2E (3) (push) Has been cancelled
CI / Desktop Smoke E2E (4) (push) Has been cancelled
CI / Desktop (push) Has been cancelled
CI / Desktop E2E Relay (push) Has been cancelled
CI / Desktop E2E Integration (1/2) (push) Has been cancelled
CI / Desktop E2E Integration (2/2) (push) Has been cancelled
CI / Desktop E2E Integration (push) Has been cancelled
CI / Backend Integration (relay e2e) (push) Has been cancelled
CI / Relay E2E (push) Has been cancelled
CI / Web (push) Has been cancelled
CI / Admin Web (push) Has been cancelled
CI / Mobile (push) Has been cancelled
CI / Security (push) Has been cancelled
CI / Server Cross-Compile (push) Has been cancelled
CI / Server Cross-Compile-1 (push) Has been cancelled
CI / Windows Rust (x86_64-pc-windows-msvc) (push) Has been cancelled
CI / Desktop Build (macOS) (push) Has been cancelled
Docker image / Merge release multi-arch manifest (push) Has been cancelled
Docker image / Merge debug multi-arch manifest (push) Has been cancelled
Docker image / Publish public push gateway image (push) Has been cancelled
docs(deploy): name the enforcement point for the chart version rule
The bullet said to bump Chart.yaml on any chart change and nothing checked
it, which is the repo's own no-vocabulary-without-an-enforcement-point
failure sitting inside the deployment contract. b6443a823 then shipped an
entire alert group under an unbumped version, and it was caught by a human
reading two files three commits later.

Worth recording why it got that far: a deploy/charts-only push matched no
glob in lefthook pre-push, so zero local hooks ran on it. The guard is now
in just check, in CI, and in pre-push.

Also records what is deliberately NOT guarded -- tests/, ci/, README.md --
because demanding a bump for a test-only edit teaches reflexive bumping,
which is the same defect wearing a hat.

Signed-off-by: Joshua Belke <joshua@innovationhub-act.org>
2026-08-21 04:34:11 -04:00

6.3 KiB

deploy/ — Charts & Compose

Purpose

How the relay is deployed: the Helm charts (the artifact ArgoCD consumes), the Docker Compose stack for self-hosting behind Caddy, and local quickstart values for a kind cluster.

Ownership

Path Owns
charts/meridian/ The relay chart — templates/ (deployment, service, ingress, httproute, hpa, pdb, servicemonitor, pvc-git, pairing-relay, bundled quickstart MinIO, secrets, _helpers.tpl, _validate.tpl, NOTES.txt), values.yaml, values.schema.json, Chart.yaml/Chart.lock, examples/, ci/, tests/
charts/meridian-push-gateway/ The APNs push-gateway chart, values-production.yaml, tests/render.sh
charts/meridian-control-plane/ The control-plane chart, values.schema.json (pins identityProvider to oidc), tests/render.sh
compose/ compose.yml + compose.dev.yml + compose.caddy.yml + compose.control-plane.yml + compose.dokploy.yml, Caddyfile, .env.example, run.sh, README.md, zenoh/zenohd.json5
local/ quickstart-ha-values.yaml, build-and-deploy.sh for local kind clusters
../ct.yaml chart-testing config (chart dir, target branch, extra args)

These charts are applied directly — there is no downstream Terraform or ArgoCD repo between a chart change and production. Images come from registry.r2d2.office.ilab.zone/meridian-*, built by this repo's own CI.

Local Contracts

  • values.schema.json is part of the contract. Every new value gets a schema entry plus a default in values.yaml. An unschematized value fails ct lint and, worse, silently no-ops in a real install.
  • Guard invalid configuration in _validate.tpl, failing the render with a readable message — do not let a bad combination produce a broken Deployment.
  • Every template change lands with a tests/*_test.yaml case. The suite (render_test, networking_test, secrets_test, hpa_test, extras_test, validation_test, pairing_relay_test, quickstart_*) is the only thing that catches a template regression before staging.
  • Bump Chart.yaml version on any chart change. ArgoCD tracks chart versions; an unbumped chart deploys stale templates. Enforced by just check-chart-version-bump — scripts/chart-version-manifest.json records each chart's rendered-file digests against the version they were recorded at, so a template edit without a bump fails without needing a diff. Run just check-chart-version-bump --write after a legitimate bump; it refuses to record an unbumped change, so there is no escape hatch. Until this landed the rule was prose only, and b6443a823 shipped a whole alert group under an unbumped version — a chart-only push matched no pre-push glob, so no local hook ran at all. tests/, ci/ and README.md are deliberately unguarded: none reaches a cluster, and demanding a bump for a test edit trains reflexive bumping.
  • Chart defaults must stay safe for a fresh install. The bundled MinIO quickstart path exists for evaluation only — production values must not depend on it.
  • Relay env additions are three-sided: crates/meridian-relay/src/config.rs, .env.example (with a comment), and the chart (values.yaml + schema + deployment template). Missing the chart side means the setting cannot be used in production.
  • Never commit real secrets. secret-chart.yaml templates references; values come from the deployment repo.
  • Compose is the self-host path and must keep working standalone — do not make it depend on cluster-only resources.
  • compose/zenoh/zenohd.json5 is the one router config, mounted read-only by every stack that runs a router — the root docker-compose.yml bus profile today, compose.yml when the multi-host arm lands. Do not copy it per stack: two copies of a security-relevant config drift and only one gets read. just compose-check parses it and asserts the Phase 5.3 contract (no REST, no storage-manager, no plugin loading, no multicast, no gossip, QoS on, lowlatency off, batching on, shared memory explicitly off).
  • A relay env var is only usable if the image builds the code that reads it. MERIDIAN_BUS=zenoh|shadow is a hard startup error unless the binary was built --features meridian-relay/zenoh, so Dockerfile and REMAPPING/cicd/Dockerfile carry that flag on both cargo chef cook and cargo build. A chart or Compose file that renders a variable the image cannot read is a crash loop, not a feature flag (meridian-nok3).
  • The proxy overlays are mutually exclusive and opposite. compose.caddy.yml adds a Caddy container and terminates TLS itself; compose.dokploy.yml assumes Dokploy's Traefik already exists and only unpublishes ports plus adds routing labels. Combining them puts two proxies on :443. A ports: entry re-added to the Dokploy overlay silently exposes the service beside the proxy rather than behind it, so both overlays tag ports: with !override/!reset.
  • Community hosts need a DNS-01 certificate resolver. They are minted under *.communities.<domain>, and Let's Encrypt issues wildcards over DNS-01 only. An HTTP-01 resolver deploys successfully and then fails per community, not at deploy time.
  • The control plane never shares the relay's database. A bare DATABASE_URL names the relay's, and migrating into it interleaves two _sqlx_migrations histories. compose.control-plane.yml provisions its own via a one-shot.

Work Guidance

  • Subchart dependencies are resolved with helm dependency build deploy/charts/meridian (CI does this before linting; ct.yaml deliberately skips remote OCI fetches).
  • Control-plane deployment procedure lives in docs/control-plane-deployment.md.
  • Push-gateway deployment procedure lives in docs/push-gateway-deployment.md; multi-tenant relay operations in docs/multi-tenant-relay.md.

Verification

helm dependency build deploy/charts/meridian
ct lint --config ct.yaml --all
helm unittest deploy/charts/meridian
deploy/charts/meridian-push-gateway/tests/render.sh
helm template deploy/charts/meridian -f deploy/charts/meridian/examples/<fixture>.yaml

The helm chart GitHub workflow runs lint + unittest + a render matrix, with a gated kind install job.

Child STELLAR Index

None — deploy/ is governed by this file, including both charts and compose/.