Skip to content

feat(k8s): Helm packaging -- library chart, per-service charts, umbrella (RFC-0003 PR-2) - #201

Merged
vovinacci merged 2 commits into
mainfrom
feat/rfc-0003-helm
Jul 28, 2026
Merged

feat(k8s): Helm packaging -- library chart, per-service charts, umbrella (RFC-0003 PR-2)#201
vovinacci merged 2 commits into
mainfrom
feat/rfc-0003-helm

Conversation

@vovinacci

@vovinacci vovinacci commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Package the polyglot platform as Helm charts, validated entirely offline (no cluster -- the Kind cluster and the Gateway are PR-3, the Prometheus Operator is PR-4).

  • A library chart (deploy/k8s/charts/common) is the D6 uniform contract made executable: a Deployment/StatefulSet, Service, ServiceAccount, resources, and probes/ServiceMonitor that default to the D6 posture (httpGet /healthz liveness, /readyz readiness, ServiceMonitor on) but are per-service opt-out. The nginx frontend is the one documented D6 exception (ADR-0013): an honest tcpSocket liveness, no /healthz probe, no ServiceMonitor -- the nginx-vs-Caddy contrast the platform teaches. The backend keeps the HTTP pair and adds a gRPC startup probe on :50051; Postgres A/B/C are StatefulSets + PVCs (ADR-0018) with the reports artifact PVC.
  • Thin per-service charts consume the library; an umbrella chart with per-profile values overlays mirrors the compose profiles (core + analytics / reports / reports-ui / synthetic / load), so helm template selects exactly a profile's services.
  • CI gate (k8s-lint.yml + make lint-k8s, make==CI): helm lint + helm template | kubeconform -strict for every profile, with a vendored ServiceMonitor CRD schema so the CR is genuinely validated (Skipped:0), never --ignore-missing. helm + kubeconform pinned in .mise.toml. yamllint/check-yaml excludes scoped to the Go-template dirs only.

Summary by CodeRabbit

  • New Features
    • Added Helm-based Kubernetes packaging for core services with optional profiles (analytics, reports, synthetic, load generation, full).
    • Introduced a reusable Helm library for shared workloads (probes, services, ServiceMonitors) and a platform umbrella chart to compose included services.
  • Bug Fixes
    • Improved Helm template YAML linting exclusions to avoid false positives on Go-template files.
  • Documentation
    • Added Kubernetes packaging and offline validation guidance, plus CI coverage notes for the new Helm/schema gate.
  • Chores
    • Added an automated, offline Helm lint and strict Kubernetes schema validation gate, including pinned lint tooling.

…lla (RFC-0003 PR-2)

Package the polyglot platform as Helm charts, validated entirely offline (no
cluster -- the Kind cluster and the Gateway are PR-3, the Prometheus Operator
is PR-4).

- A library chart (deploy/k8s/charts/common) is the D6 uniform contract made
  executable: a Deployment/StatefulSet, Service, ServiceAccount, resources,
  and probes/ServiceMonitor that default to the D6 posture (httpGet /healthz
  liveness, /readyz readiness, ServiceMonitor on) but are per-service opt-out.
  The nginx frontend is the one documented D6 exception (ADR-0013): an honest
  tcpSocket liveness, no /healthz probe, no ServiceMonitor -- the nginx-vs-Caddy
  contrast the platform teaches. The backend keeps the HTTP pair and adds a
  gRPC startup probe on :50051; Postgres A/B/C are StatefulSets + PVCs
  (ADR-0018) with the reports artifact PVC.
- Thin per-service charts consume the library; an umbrella chart with
  per-profile values overlays mirrors the compose profiles (core + analytics /
  reports / reports-ui / synthetic / load), so `helm template` selects exactly
  a profile's services.
- CI gate (k8s-lint.yml + make lint-k8s, make==CI): helm lint + helm template |
  kubeconform -strict for every profile, with a vendored ServiceMonitor CRD
  schema so the CR is genuinely validated (Skipped:0), never --ignore-missing.
  helm + kubeconform pinned in .mise.toml. yamllint/check-yaml excludes scoped
  to the Go-template dirs only.
@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 73a9462a-e8ac-466c-8f3f-557b2d5a539a

📥 Commits

Reviewing files that changed from the base of the PR and between 096b3f3 and be4001c.

📒 Files selected for processing (6)
  • .github/workflows/k8s-lint.yml
  • .yamllint.yml
  • deploy/k8s/README.md
  • deploy/k8s/charts/common/templates/_probes.tpl
  • deploy/k8s/charts/common/templates/_workload.tpl
  • deploy/k8s/charts/reports/values.yaml
🚧 Files skipped from review as they are similar to previous changes (5)
  • .github/workflows/k8s-lint.yml
  • deploy/k8s/charts/reports/values.yaml
  • deploy/k8s/charts/common/templates/_workload.tpl
  • deploy/k8s/charts/common/templates/_probes.tpl
  • deploy/k8s/README.md

Walkthrough

Adds a shared Helm library, charts for platform services and profile overlays, and an offline validation gate. Local Make targets and CI now run Helm linting, profile rendering, and strict kubeconform validation using pinned tools and a vendored ServiceMonitor schema.

Changes

Kubernetes packaging

Layer / File(s) Summary
Shared Helm library templates
deploy/k8s/charts/common/...
Adds reusable helpers and templates for labels, images, ports, probes, services, monitoring, deployments, StatefulSets, and persistent storage.
Service chart definitions and values
deploy/k8s/charts/{analytics,backend,blackbox,canary,frontend,loadgen,loki,mailpit,postgres,postgres-exporter,reports,reports-ui}/...
Adds chart metadata, common-library includes, and service-specific runtime, health, monitoring, and persistence values.
Platform umbrella and profiles
deploy/k8s/charts/platform/...
Adds conditional service dependencies, core defaults, and additive analytics, reports, synthetic, load, reports UI, and full profile overlays.
Offline validation and CI integration
.github/workflows/k8s-lint.yml, deploy/k8s/scripts/validate.sh, deploy/k8s/schemas/..., Makefile, .mise.toml, .pre-commit-config.yaml, .yamllint.yml, docs/ci.md
Adds pinned Helm and kubeconform tooling, strict profile validation, a vendored ServiceMonitor schema, lint exclusions, Make integration, CI execution, and documentation.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Developer
  participant Makefile
  participant ValidateScript
  participant Helm
  participant Kubeconform
  Developer->>Makefile: run lint-k8s
  Makefile->>ValidateScript: execute validate.sh
  ValidateScript->>Helm: lint and render chart profiles
  Helm-->>ValidateScript: rendered manifests
  ValidateScript->>Kubeconform: strict schema validation
  Kubeconform-->>Developer: validation result
Loading

Poem

I’m a rabbit with charts in my pack,
Helm hops forward on a well-pinned track.
Probes bloom, profiles align,
Schemas guard each rendered line,
And CI thumps its paws: “All fine!”

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly reflects the main change: adding Helm packaging with a library chart, per-service charts, and an umbrella chart.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/rfc-0003-helm

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🧹 Nitpick comments (5)
deploy/k8s/charts/common/templates/_workload.tpl (2)

95-117: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

Consider extracting a shared common.container.

The StatefulSet pod spec duplicates the Deployment's container block (image, pullPolicy, ports, env, probes, resources, volumeMounts) and has already drifted: command/args are honoured only in common.deployment. A single common.container helper would keep the two workload shapes in step, in the spirit of the "uniformity enforced by this one template" comment at the top of the file.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@deploy/k8s/charts/common/templates/_workload.tpl` around lines 95 - 117,
Extract the duplicated container definition into a shared common.container
helper containing image, pullPolicy, ports, env, probes, command/args,
resources, and volumeMounts. Update both common.deployment and the StatefulSet
workload template to render this helper, preserving the existing container name
and indentation so both workload shapes remain consistent.

118-131: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Guard volumeClaimTemplates so the key is not emitted empty.

volumeClaimTemplates: is emitted unconditionally. A consumer without a persistence key fails to render (nil pointer on .volumeClaimTemplates's parent), and one with an empty volumeClaims list renders volumeClaimTemplates: null, which kubeconform -strict rejects. Only charts/postgres uses this today, so wrap it while the contract is still cheap to fix.

♻️ Proposed guard
-  volumeClaimTemplates:
-    {{- range .Values.persistence.volumeClaims }}
+  {{- with (.Values.persistence).volumeClaims }}
+  volumeClaimTemplates:
+    {{- range . }}
     - metadata:
         name: {{ .name }}
       spec:
         accessModes:
           - {{ .accessMode | default "ReadWriteOnce" }}
         resources:
           requests:
             storage: {{ .size | default "1Gi" }}
         {{- with .storageClassName }}
         storageClassName: {{ . }}
         {{- end }}
     {{- end }}
+  {{- end }}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@deploy/k8s/charts/common/templates/_workload.tpl` around lines 118 - 131,
Guard the volumeClaimTemplates block around the existing
persistence.volumeClaims range so the key is emitted only when
persistence.volumeClaims is defined and non-empty. Preserve the current claim
rendering and defaults, while ensuring workloads without persistence or with an
empty volumeClaims list omit volumeClaimTemplates entirely rather than rendering
null.
deploy/k8s/charts/common/templates/_probes.tpl (1)

24-40: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Fail loudly on an unrecognised probe type.

An unknown/mistyped type (e.g. tcpsocket, http) matches no branch, so the probe renders with only the timing fields and no handler. That is schema-valid, so kubeconform -strict passes and the misconfiguration reaches the cluster silently — precisely the "opt-out is a named posture, not a hole" property this file documents. An explicit fail keeps the contract enforced at render time.

♻️ Proposed guard
 {{- else if eq $type "exec" }}
 exec:
   command:
     {{- toYaml .command | nindent 4 }}
+{{- else if ne $type "none" }}
+{{- fail (printf "common.probeHandler: unsupported probe type %q (httpGet|tcpSocket|grpc|exec|none)" $type) }}
 {{- end }}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@deploy/k8s/charts/common/templates/_probes.tpl` around lines 24 - 40, Update
the common.probeHandler template to add an explicit fallback after the supported
httpGet, tcpSocket, grpc, and exec branches that fails rendering for any
unrecognised .type value, including the invalid type in the error message.
Preserve the existing handlers and defaults unchanged.
deploy/k8s/schemas/monitoring.coreos.com/servicemonitor_v1.json (1)

1-3: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Record the provenance of this vendored schema.

JSON has no comment syntax, so nothing here states which prometheus-operator release the CRD was extracted from or how to regenerate it. Since this file is the load-bearing part of the DK9 gate, it will silently drift from the operator version PR-4 installs. Please note the upstream source URL and operator tag in deploy/k8s/README.md (next to the schemas/ layout entry), or add a small Makefile target that refreshes it.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@deploy/k8s/schemas/monitoring.coreos.com/servicemonitor_v1.json` around lines
1 - 3, Document the vendored ServiceMonitor schema’s provenance in
deploy/k8s/README.md near the schemas/ layout entry, including the upstream
prometheus-operator source URL, exact operator release tag, and regeneration
procedure; do not modify the JSON schema itself.
deploy/k8s/charts/postgres-exporter/values.yaml (1)

31-35: 🩺 Stability & Availability | 🔵 Trivial

Gate ServiceMonitor use on CRD availability.

serviceMonitor.enabled: true renders a Prometheus Operator resource, but this PR does not install the ServiceMonitor CRD. Ensure installation ordering or keep this chart disabled until the operator dependency is present.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@deploy/k8s/charts/postgres-exporter/values.yaml` around lines 31 - 35, Update
the serviceMonitor configuration in values.yaml so it is not enabled by default
unless the Prometheus Operator ServiceMonitor CRD is guaranteed to be installed
first; otherwise set serviceMonitor.enabled to false and preserve the existing
path, port, and interval settings.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/k8s-lint.yml:
- Around line 10-20: Add "Makefile" to the paths filters for both the
pull_request and push triggers in the k8s-lint workflow, preserving all existing
path entries.

In @.yamllint.yml:
- Around line 22-27: Rename the top-level configuration key from exclude to
ignore in the yamllint configuration, preserving the existing exclusion patterns
for frontend dependencies, Grafana dashboards, and Helm chart templates.

In `@deploy/k8s/charts/backend/values.yaml`:
- Around line 46-50: Disable d6.serviceMonitor.enabled by default in
deploy/k8s/charts/backend/values.yaml (lines 46-50) and
deploy/k8s/charts/reports-ui/values.yaml (lines 30-34), so ServiceMonitor
resources are not rendered until the Prometheus Operator CRD is installed;
preserve the existing ServiceMonitor configuration for users who explicitly
enable it.

In `@deploy/k8s/charts/common/values.yaml`:
- Around line 1-37: Add an ADR or RFC amendment documenting the shared values
contract represented by the common values template, including images, ports,
probes, persistence, ServiceMonitors, and compatibility expectations. Reference
the contract symbols and fields shown in the common values definition, and
follow the repository’s existing ADR/RFC format and numbering conventions.

In `@deploy/k8s/charts/platform/Chart.yaml`:
- Around line 18-83: Add the required ADR/RFC amendment for the new Helm service
contract represented by the dependencies in the Chart.yaml section. Document
each service’s values contract, the postgres aliases (postgres-backend,
postgres-analytics, and postgres-reports), and how the enabled conditions and
profiles control deployment.

In `@deploy/k8s/charts/platform/values.yaml`:
- Around line 33-41: Replace the literal analytics POSTGRES_PASSWORD in the env
block near deploy/k8s/charts/platform/values.yaml lines 33-41 with a
valueFrom.secretKeyRef pointing to the appropriate externally supplied Secret
key, preserving the existing POSTGRES_DB, POSTGRES_USER, and PGDATA entries.
Apply the same Secret-backed change to the reports POSTGRES_PASSWORD near lines
61-69; do not commit plaintext credentials.

In `@deploy/k8s/charts/postgres/values.yaml`:
- Around line 20-21: Update the POSTGRES_PASSWORD entry in the chart values to
use valueFrom.secretKeyRef referencing an externally managed Kubernetes Secret
and its password key. Remove the literal app value entirely, with no fallback or
other committed plaintext credential.

In `@deploy/k8s/charts/reports/values.yaml`:
- Around line 33-40: Update the reports chart configuration around extraPVCs and
pvcMounts to prevent rolling updates from creating concurrent pods that contend
for the ReadWriteOnce artifacts claim. Configure the Deployment with a Recreate
strategy, or change the claim to ReadWriteOncePod or an RWX-capable storage
mode, while preserving the existing artifact mount.

---

Nitpick comments:
In `@deploy/k8s/charts/common/templates/_probes.tpl`:
- Around line 24-40: Update the common.probeHandler template to add an explicit
fallback after the supported httpGet, tcpSocket, grpc, and exec branches that
fails rendering for any unrecognised .type value, including the invalid type in
the error message. Preserve the existing handlers and defaults unchanged.

In `@deploy/k8s/charts/common/templates/_workload.tpl`:
- Around line 95-117: Extract the duplicated container definition into a shared
common.container helper containing image, pullPolicy, ports, env, probes,
command/args, resources, and volumeMounts. Update both common.deployment and the
StatefulSet workload template to render this helper, preserving the existing
container name and indentation so both workload shapes remain consistent.
- Around line 118-131: Guard the volumeClaimTemplates block around the existing
persistence.volumeClaims range so the key is emitted only when
persistence.volumeClaims is defined and non-empty. Preserve the current claim
rendering and defaults, while ensuring workloads without persistence or with an
empty volumeClaims list omit volumeClaimTemplates entirely rather than rendering
null.

In `@deploy/k8s/charts/postgres-exporter/values.yaml`:
- Around line 31-35: Update the serviceMonitor configuration in values.yaml so
it is not enabled by default unless the Prometheus Operator ServiceMonitor CRD
is guaranteed to be installed first; otherwise set serviceMonitor.enabled to
false and preserve the existing path, port, and interval settings.

In `@deploy/k8s/schemas/monitoring.coreos.com/servicemonitor_v1.json`:
- Around line 1-3: Document the vendored ServiceMonitor schema’s provenance in
deploy/k8s/README.md near the schemas/ layout entry, including the upstream
prometheus-operator source URL, exact operator release tag, and regeneration
procedure; do not modify the JSON schema itself.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 566e3f61-3afe-47c2-8581-f5b0fcc69e47

📥 Commits

Reviewing files that changed from the base of the PR and between 0bbbb99 and 096b3f3.

📒 Files selected for processing (62)
  • .github/workflows/k8s-lint.yml
  • .mise.toml
  • .pre-commit-config.yaml
  • .yamllint.yml
  • Makefile
  • deploy/k8s/.gitignore
  • deploy/k8s/README.md
  • deploy/k8s/charts/analytics/Chart.yaml
  • deploy/k8s/charts/analytics/templates/manifests.yaml
  • deploy/k8s/charts/analytics/values.yaml
  • deploy/k8s/charts/backend/Chart.yaml
  • deploy/k8s/charts/backend/templates/manifests.yaml
  • deploy/k8s/charts/backend/values.yaml
  • deploy/k8s/charts/blackbox/Chart.yaml
  • deploy/k8s/charts/blackbox/templates/manifests.yaml
  • deploy/k8s/charts/blackbox/values.yaml
  • deploy/k8s/charts/canary/Chart.yaml
  • deploy/k8s/charts/canary/templates/manifests.yaml
  • deploy/k8s/charts/canary/values.yaml
  • deploy/k8s/charts/common/Chart.yaml
  • deploy/k8s/charts/common/templates/_helpers.tpl
  • deploy/k8s/charts/common/templates/_networking.tpl
  • deploy/k8s/charts/common/templates/_ports.tpl
  • deploy/k8s/charts/common/templates/_probes.tpl
  • deploy/k8s/charts/common/templates/_workload.tpl
  • deploy/k8s/charts/common/values.yaml
  • deploy/k8s/charts/frontend/Chart.yaml
  • deploy/k8s/charts/frontend/templates/manifests.yaml
  • deploy/k8s/charts/frontend/values.yaml
  • deploy/k8s/charts/loadgen/Chart.yaml
  • deploy/k8s/charts/loadgen/templates/manifests.yaml
  • deploy/k8s/charts/loadgen/values.yaml
  • deploy/k8s/charts/loki/Chart.yaml
  • deploy/k8s/charts/loki/templates/manifests.yaml
  • deploy/k8s/charts/loki/values.yaml
  • deploy/k8s/charts/mailpit/Chart.yaml
  • deploy/k8s/charts/mailpit/templates/manifests.yaml
  • deploy/k8s/charts/mailpit/values.yaml
  • deploy/k8s/charts/platform/Chart.yaml
  • deploy/k8s/charts/platform/templates/NOTES.txt
  • deploy/k8s/charts/platform/values-analytics.yaml
  • deploy/k8s/charts/platform/values-full.yaml
  • deploy/k8s/charts/platform/values-load.yaml
  • deploy/k8s/charts/platform/values-reports-ui.yaml
  • deploy/k8s/charts/platform/values-reports.yaml
  • deploy/k8s/charts/platform/values-synthetic.yaml
  • deploy/k8s/charts/platform/values.yaml
  • deploy/k8s/charts/postgres-exporter/Chart.yaml
  • deploy/k8s/charts/postgres-exporter/templates/manifests.yaml
  • deploy/k8s/charts/postgres-exporter/values.yaml
  • deploy/k8s/charts/postgres/Chart.yaml
  • deploy/k8s/charts/postgres/templates/manifests.yaml
  • deploy/k8s/charts/postgres/values.yaml
  • deploy/k8s/charts/reports-ui/Chart.yaml
  • deploy/k8s/charts/reports-ui/templates/manifests.yaml
  • deploy/k8s/charts/reports-ui/values.yaml
  • deploy/k8s/charts/reports/Chart.yaml
  • deploy/k8s/charts/reports/templates/manifests.yaml
  • deploy/k8s/charts/reports/values.yaml
  • deploy/k8s/schemas/monitoring.coreos.com/servicemonitor_v1.json
  • deploy/k8s/scripts/validate.sh
  • docs/ci.md

Comment thread .github/workflows/k8s-lint.yml
Comment thread .yamllint.yml
Comment thread deploy/k8s/charts/backend/values.yaml
Comment thread deploy/k8s/charts/common/values.yaml
Comment thread deploy/k8s/charts/platform/Chart.yaml
Comment thread deploy/k8s/charts/platform/values.yaml
Comment thread deploy/k8s/charts/postgres/values.yaml
Comment thread deploy/k8s/charts/reports/values.yaml
…ts gate

Each of these passes `helm template | kubeconform -strict` today and fails
somewhere later, which is the failure mode DK9 exists to prevent.

- A mistyped probe `type` matched no branch and rendered a probe with timing
  fields and no handler. kubeconform accepts that (every handler is optional
  in the schema); the API server does not. The typo would have survived the
  gate and surfaced at install. Unknown types now fail at render.
- `common.statefulset` read `.Values.persistence.volumeClaims` unguarded, so a
  chart without a `persistence` key could not render at all, and an empty list
  emitted a null `volumeClaimTemplates`. Both are now absent instead.
- The reports artifact PVC is ReadWriteOnce, but the Deployment took the
  default rolling update: the surge pod is scheduled before the old one
  releases the volume and, on any other node of a multi-node cluster, never
  attaches. Reports now uses Recreate, via a new optional `strategy` value on
  the shared Deployment template.

Two gate repairs alongside them:

- `.yamllint.yml` used `exclude:`, which yamllint does not support and
  silently ignores, so none of the three exclusions applied. Only prek's own
  regex kept chart templates out of the linter. Renamed to `ignore:`.
- The chart workflow runs `make lint-k8s` but did not watch `Makefile`, so a
  change to the target skipped its own gate. Other workflows already list it.

The vendored ServiceMonitor schema is the load-bearing part of the gate and
recorded no provenance; its source, regeneration command, and the fact that
its operator release is still unpinned are now written down.
@vovinacci
vovinacci merged commit 14a08e7 into main Jul 28, 2026
9 checks passed
@vovinacci
vovinacci deleted the feat/rfc-0003-helm branch July 28, 2026 19:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant