Imported from CartoDB/carto-selfhosted-helm (
AGENTS.md). Install upstream withnpx skills add CartoDB/carto-selfhosted-helm. Copyright stays with the author.
AGENTS.md
Instructions for AI coding agents and the people pairing with them. Every tool
reads this file; CLAUDE.md only imports it. Subtree specifics live next to
the code in chart/CLAUDE.md and manifests/CLAUDE.md; path-scoped rules in
.claude/rules/ — see Path-scoped guidance.
⚠️ PUBLIC repository — information disclosure rules
Everything pushed here is world-readable the moment it lands: code, comments, commit messages, branch names, PR titles and bodies, and these instruction files themselves.
Before writing any name, value, URL, or process detail, apply one test:
is it already public in this repo? (git grep it). If it isn't, and it
comes from CARTO's internal world, leave it out or genericize it.
Never write:
- Secrets — real or realistic-looking. A random-looking hex string as a
placeholder secret gets copy-pasted and triggers scanners; defaults in
values.yamlare empty strings, keep it that way. - Internal infrastructure names: GCP project IDs, cluster or hostnames, IPs.
A debug crumb like
# tested on gke_carto-internal-x_us-east1is a leak. - Anything from a customer: company names, tenant IDs, domains, support
bundle contents, their
values.yaml. Not in code, not in PR bodies, not in test fixtures. - Internal URLs: Slack channels or archive links, Shortcut story URLs, internal dashboards or wiki pages.
- Internal-only tooling or process that isn't observable from this repo's own files and workflows.
Fine, because it is already public here or established practice:
registry.self-hosted.carto.comand the default image registries/repos inchart/values.yamlandmanifests/kots-helm.yaml.- Short Shortcut refs
[sc-XXXXXX]in commit messages and PR titles — the ID only, never the full URL. - Links to public docs (
docs.carto.com).
What this repo is
A Helm chart that deploys CARTO Self-Hosted, shipped two ways:
- Pure Helm —
helm install carto ./chart -f values.yaml. - Replicated / KOTS — the same chart wrapped by
manifests/kots-*.yamlfor the KOTS Admin Console and embedded-cluster (single-VM) installs.
Container images come from CARTO's application services; what lives here is values, templates, validation, and the KOTS translation layer.
Two rules everything follows: the Helm chart is the source of truth, and KOTS only translates customer input into chart values. A change must work in both paths — Helm-only or KOTS-only is half done.
Process detail (git setup, doc generation, linting, branching) is in
CONTRIBUTING.md. Full chart params are in the generated
chart/README.md.
The values flow
manifests/kots-config.yaml (KOTS UI: items + RandomString secrets)
└─► manifests/kots-helm.yaml (ConfigOption → chart values)
└─► chart/values.yaml (Helm defaults)
└─► chart/templates/<component>/* (consume the value, usually via _helpers.tpl)
└─► Kubernetes resources
The most common change here is wiring an env var. Plain config → the
component's configmap.yaml and done. Customer-set → also values.yaml
(with a ## @param comment), kots-config.yaml, and kots-helm.yaml, shipped
together. Secret → the secretAssociation machinery (see
chart/CLAUDE.md).
Finding your way
The big files are uniform or generated: grep them, don't read them.
| Looking for | Do |
|---|---|
A parameter in chart/values.yaml (7,000+ lines) |
grep -n '^## @section' chart/values.yaml is the table of contents; then grep -n '@param <dotted.path>' |
| A component's helpers | grep -n 'define "carto.<component>\.' chart/templates/_helpers.tpl — uniform per component (fullname, configmapName, secretName, image, …) |
| The validators | grep -n 'define "carto.validateValues\.' chart/templates/_validators.tpl |
| What feeds an env var | grep -rn 'THE_ENV_VAR' chart/templates/ — a hit in a configmap.yaml is plain config; a hit in _helpers.tpl is the secretAssociation map |
| Which KOTS field sets a value | grep -n '<valuesKey>' manifests/kots-helm.yaml, then that ConfigOption name in manifests/kots-config.yaml |
| What an install scenario renders | helm template carto ./chart -f <your-values>.yaml, plain and with --set replicated.enabled=true |
chart/README.md is generated from chart/values.yaml — never edit it by hand.
Versioning
Version fields (VERSION, Chart.yaml#version/appVersion/minVersion,
kots-helm.yaml#chartVersion) are bot-driven: the release pipeline opens a
:rocket: Update to … PR that sets them all atomically. Don't bump them by
hand. The only exception is a chart-only hotfix with no app release — then
keep Chart.yaml#version == kots-helm.yaml#spec.chart.chartVersion yourself
and leave the rest alone. minVersion semantics are in chart/CLAUDE.md.
Validating a change
CI is the gate — push and track it. The one thing CI won't fix for you: if you
change chart/values.yaml, regenerate chart/README.md (commands in
CONTRIBUTING.md) or the drift check blocks the PR. For a quick local sanity
check, helm template both paths: plain and --set replicated.enabled=true
(on a fresh clone, fetch the subcharts first:
helm repo add bitnami https://charts.bitnami.com/bitnami and
helm dependency build chart).
Before you push
Both helm template paths render, and:
- Both install paths. A customer-set value has its KOTS field
(
kots-config.yaml+kots-helm.yaml), or the PR says why it is Helm-only. - Resources. A changed
resourcesblock needs the public docs updated and a release-notes ticket. - Version fields untouched.
- No AI residue. No comments narrating what was generated or why an alternative was rejected, no commented-out code, no debug values, no placeholder secrets.
- Terse, public PR body — what changed, why, how it was validated.
Conventions
- Conventional commits, scoped to what you touched (common scopes:
chart,selfhosted,router,ci). - Branch off
main; usesc-<id>/in the branch name to auto-link the Shortcut story. Open PRs as draft. - The
release-changesPR label publishes the branch's chart to a per-branch Replicated dev channel for install testing; removing the label or closing the PR tears it down.
Path-scoped guidance
Claude Code loads .claude/rules/*.md by path automatically. Other tools: read
the row's files before editing that path.
| Editing | Read first |
|---|---|
chart/templates/** |
chart/CLAUDE.md, .claude/rules/helm-templates.md |
chart/values.yaml, chart/README.md |
chart/CLAUDE.md, .claude/rules/values-yaml.md |
manifests/** |
manifests/CLAUDE.md, .claude/rules/kots-manifests.md |
Every change ships to customers running on their own infrastructure. They cannot quickly roll back, and we cannot quickly redeploy. Measure twice, cut once.
