{"owner":"prometheus-community","repo":"helm-charts","hasSkills":true,"totalSkillsCount":5,"totalTokensCount":7482,"categories":["anthropic-skill","root-instruction","copilot-instructions"],"hasMcp":false,"mcpConfig":null,"found":[".agents/skills/helm-values-schema/SKILL.md","AGENTS.md",".github/copilot-instructions.md",".agents/skills/bump-prometheus-operator/SKILL.md",".agents/skills/helm-chart-test/SKILL.md"],"skills":{".agents/skills/helm-values-schema/SKILL.md":"---\nname: helm-values-schema\ndescription: Maintain values.schema.json for Helm charts that use helm-values-schema-json annotations in values.yaml.\nuser_invocable: true\n---\n\n# /helm-values-schema [chart]\n\nUse this skill when the user asks to add, change, review, or regenerate a Helm chart `values.schema.json`, or when a chart feature changes `values.yaml` in a chart that uses schema annotations.\n\n## Detection\n\nA chart uses `helm-values-schema-json` if `charts/<chart>/values.yaml` contains either:\n\n- `# @schema` comments\n- a top-level schema reference such as `# $schema: ./values.schema.json`\n\nWhen a chart uses this flow, changes to `values.yaml` must keep schema annotations and `values.schema.json` in sync.\n\n## Documentation\n\nPrefer Context7 for current `helm-values-schema-json` docs when available.\n\nUpstream documentation:\n\n```text\nhttps://github.com/losisin/helm-values-schema-json/blob/main/docs/README.md\n```\n\n## Compatibility\n\nHelm validates chart values with JSON Schema draft-07. Keep generated schemas compatible with draft-07 even if external schema tooling supports newer drafts.\n\n## Workflow\n\n1. Read `charts/<chart>/values.yaml`.\n2. Check whether `# @schema` annotations or `# $schema: ./values.schema.json` are present.\n3. If changing or adding values, preserve nearby annotations and add annotations when inferred schema would be wrong or too loose.\n4. Preserve helm-docs comments. When a field has both `# @schema` and helm-docs `# --` comments, `# @schema` comments must be above the helm-docs description comments.\n5. Regenerate `values.schema.json`.\n6. Review the schema diff for only intentional changes.\n7. Ensure values changes also have helm-unittest coverage for rendered behavior where applicable.\n\n## helm-docs Integration\n\n`helm-values-schema-json` supports using descriptions from `helm-docs` comments since v2.0.0, but only when enabled with `--use-helm-docs`.\n\nExample:\n\n```bash\nhelm schema --use-helm-docs\n```\n\n```yaml\n# -- My description\nfullnameOverride: bar\n```\n\nGenerates:\n\n```json\n{\n  \"fullnameOverride\": {\n    \"description\": \"My description\",\n    \"type\": \"string\"\n  }\n}\n```\n\n### Unsupported helm-docs Features\n\nThe schema plugin does not support helm-docs-specific properties such as:\n\n- `# @default --`\n- `# @section --`\n\nIt also does not support detached helm-docs comments. Comments must be directly above the property or inline in a supported form.\n\nSupported:\n\n```yaml\n# fullnameOverride -- This works\nfullnameOverride: bar\n```\n\nNot supported by the schema plugin:\n\n```yaml\nfullnameOverride: bar\n\n# fullnameOverride -- This does not work for schema generation.\nfullnameOverride: bar\n```\n\nHelm-docs itself does not understand `# @schema` comments. When both `# @schema` and helm-docs comments are above a field, put `# @schema` first so schema annotations are not included in the generated description. Treat the inverse order as invalid: helm-docs will include the schema annotation text in the description.\n\nGood:\n\n```yaml\n# @schema maxLength:10\n# -- My awesome nameOverride description\nnameOverride: \"myapp\"\n```\n\nBad:\n\n```yaml\n# -- My awesome nameOverride description\n# @schema maxLength:10\nnameOverride: \"myapp\"\n```\n\n## Annotation Placement\n\n`# @schema` annotations may be placed inline, on the line above a field, or in specific cases below a block. Preserve the surrounding style already used in the chart, except when the existing style conflicts with helm-docs ordering. If a value has a helm-docs `# --` description, any standalone `# @schema` comments for that value must be above the `# --` comment, never between the helm-docs comment and the value.\n\nExamples:\n\n```yaml\nfullnameOverride: \"myapp\" # @schema maxLength:10;pattern:^[a-z]+$\n\n# @schema maxLength:10;pattern:^[a-z]+$\nnameOverride: \"myapp\"\n\n# @schema maxLength:10\n# -- My awesome nameOverride description\nnameOverride: \"myapp\"\n\n# Invalid with helm-docs: the schema annotation becomes part of the description.\n# -- My awesome nameOverride description\n# @schema maxLength:10\nnameOverride: \"myapp\"\n\nresources:\n  limits: {}\n  requests: {}\n# @schema additionalProperties:false\n```\n\nMultiple schema annotations can be separated with semicolons.\n\n## Commands\n\nFor Loki, use the repository target:\n\n```bash\nmake helm-schema HELM_CHART=loki\n```\n\nThe underlying command currently runs:\n\n```bash\nhelm schema --config .github/linters/.schema.yaml -f charts/loki/values.yaml -o charts/loki/values.schema.json\n```\n\nIf adding schema generation for another chart, follow the chart's local Makefile or CI pattern instead of inventing a one-off command.\n\n## Rules\n\n- Do not hand-edit `values.schema.json` when it can be regenerated.\n- Do not remove existing `# @schema` annotations unless the associated value is removed.\n- Keep schema annotations as close as possible to the value they describe.\n- Keep `# @schema` comments above helm-docs `# --` comments. Never add a standalone `# @schema` comment below a helm-docs description comment for the same value.\n- Include regenerated `values.schema.json` in the change.\n- Values changes that affect rendered manifests should also be covered by helm-unittest tests.\n","AGENTS.md":"# Instructions for AI Agents\n\nThe following guidelines apply to all files in this repository.\n\n## Repository Overview\n\nThis is the **Prometheus Community Helm Charts** repository — a collection of Helm charts for Prometheus ecosystem components. Charts are published to both a Helm repository (`prometheus-community`) and as OCI artifacts on `ghcr.io`.\n\n## Charts\n\nAll charts live under `charts/` with a subfolder for each chart.  The subfolder names must match the chart name as described in the Chart.yaml file `.name`.\n\nEach chart follows standard Helm structure (`Chart.yaml`, `values.yaml`, `templates/`). Some charts will organize components into subdirectories (e.g., `templates/grafana/`, `templates/prometheus/`, `templates/alertmanager/` in `kube-prometheus-stack`).\n\n## Feature Implementation Workflow\n\nMost agent tasks in this repository are chart feature changes. For these tasks:\n\n1. Identify the affected chart under `charts/<chart>/` and keep changes scoped to that chart.\n2. Read the relevant `Chart.yaml`, `values.yaml`, templates, helpers, and existing tests before editing.\n3. Implement the feature using the chart's existing template style and values structure.\n4. If `values.yaml` changes in a schema-enabled chart, update schema annotations and regenerate `values.schema.json`.\n5. Add or update focused helm-unittest coverage for the rendered behavior controlled by the feature.\n6. Bump the chart version in `Chart.yaml` according to SemVer.\n7. Run the relevant validation commands, normally `helm unittest --strict --file 'unittests/**/*.yaml' charts/<chart-name>` and any required schema generation command.\n\nAsk the user for clarification only when the intended chart, feature behavior, or compatibility impact cannot be inferred from the request and local context.\n\n## Values Schema\n\nSome charts generate `values.schema.json` from `values.yaml` using `helm-values-schema-json`. A chart uses this flow if `values.yaml` contains `# @schema` comments or a top-level `# $schema: ./values.schema.json` comment. Upstream documentation lives at https://github.com/losisin/helm-values-schema-json/blob/main/docs/README.md; use Context7 for current docs when available.\n\nHelm validates chart values with JSON Schema draft-07. Keep generated schemas compatible with draft-07 even if external schema tooling supports newer drafts.\n\nWhen changing `values.yaml` in a schema-enabled chart:\n\n- Use the `helm-values-schema` skill for detailed schema annotation and regeneration rules.\n- Preserve and update nearby `# @schema` annotations.\n- Add `# @schema` annotations when inferred schema types would be wrong or too loose.\n- Keep `# @schema` comments before helm-docs comments (`# -- ...`) when both are present.\n- Regenerate `values.schema.json` with `helm schema` from the chart directory and include it in the change.\n- Add or update helm-unittest coverage for rendered behavior controlled by the changed values.\n\n## pre-commit testing\n\n### helm-unittests\n\nPull Requests against this repository require that all charts which implement helm-unittests(https://github.com/helm-unittest/helm-unittest) must pass all of their unittests. CI runs them as an `additional-commands` entry of `ct lint` (see `.github/linters/ct.yaml`). The same command run from the repository root:\n\n```bash\nhelm unittest --strict --file 'unittests/**/*.yaml' charts/<chart-name>\n```\n\n### per-chart lint scripts\n\nA chart may carry a `ci/lint.sh`, which `ct lint` runs in addition to the unittests. `kube-prometheus-stack` uses it to verify that the generated CRDs, rules and dashboards are in sync, so changes there have to be produced by the scripts under `hack/` rather than edited in place.\n\n## Contributing Conventions\n\n- **One chart per PR**: CI enforces that PRs only change a single chart.\n- **PR title format**: Must start with `[chart-name] ` (e.g., `[grafana] Add new feature`).\n- **Version bumps**: Every chart change (excluding files listed in `.helmignore`) requires a SemVer version bump in `Chart.yaml`. Major bumps for breaking changes.\n- **DCO sign-off**: Commits must include `Signed-off-by` line (`git commit -s`).\n- **Squash merge only**: The repository only allows squash merges.\n- **Generated files**: `.github/CODEOWNERS`, `MAINTAINERS.md` and `.github/advanced-issue-labeler.yml` are generated from `charts/` by `scripts/generate-codeowners.sh`, `scripts/generate-maintainers.sh` and `scripts/generate-labeler.sh`. Do not edit them directly.\n- **Minimum Kubernetes version**: Charts that declare `kubeVersion` in `Chart.yaml` use a `>=` range, and the value differs per chart (`>=1.25.0-0` for `kube-prometheus-stack`, lower elsewhere). Most charts declare none at all. Match the chart you are editing instead of assuming a repository-wide floor.\n\n## Dependency Management\n\nRenovate manages all dependency updates.\n",".github/copilot-instructions.md":"# GitHub Copilot Instructions\n\nFollow the repository-wide agent guidance in `AGENTS.md`. This repository contains Helm charts for Prometheus ecosystem components.\n\nMost tasks are Helm chart feature changes. When changing a chart:\n\n- Work within a single chart under `charts/<chart>/`.\n- Read `Chart.yaml`, `values.yaml`, relevant templates, helpers, and existing tests before editing.\n- Follow existing chart patterns before adding new structure.\n- Update `values.yaml`, templates, tests, and generated schema artifacts together when a new value changes rendered behavior.\n- If `values.yaml` contains `# @schema` comments or `# $schema: ./values.schema.json`, follow the `helm-values-schema` skill guidance and regenerate `values.schema.json`.\n- Add or update helm-unittest coverage for rendered behavior changed by templates or values.\n- Run `helm unittest --strict --file 'unittests/**/*.yaml' charts/<chart-name>` for charts with helm-unittest coverage.\n- Bump the chart version in `Chart.yaml` for chart changes not ignored by `.helmignore`.\n- Do not edit generated ownership files such as `.github/CODEOWNERS` or `MAINTAINERS.md` directly.\n",".agents/skills/bump-prometheus-operator/SKILL.md":"---\nname: bump-prometheus-operator\ndescription: >-\n  Bump the prometheus-operator version shipped by the kube-prometheus-stack\n  chart. Use when a new prometheus-operator/prometheus-operator release is out\n  and the chart's appVersion needs to follow it: syncs CRDs, checks for new CRD\n  kinds, RBAC changes and newly added spec fields, bumps the chart version,\n  updates UPGRADE.md, and opens a PR. Triggers on \"bump prometheus-operator\",\n  \"update kube-prometheus-stack to the latest operator\", \"sync operator CRDs\".\n---\n\n# Bump prometheus-operator in kube-prometheus-stack\n\nPromotes the `appVersion` of `charts/kube-prometheus-stack` to a new\n`prometheus-operator/prometheus-operator` release and brings everything that\ntravels with the operator (CRDs, RBAC, upgrade notes) along with it.\n\n## Scope of an operator bump\n\nThe operator version is the chart's `appVersion`. A bump touches a small,\nfixed set of files — mirror the most recent merged bump PR (search\n`git log --oneline -S \"appVersion: v\" -- charts/kube-prometheus-stack/Chart.yaml`)\nrather than improvising:\n\n- `charts/kube-prometheus-stack/Chart.yaml` — `appVersion` + chart `version`\n- `charts/kube-prometheus-stack/charts/crds/crds/crd-*.yaml` (10 CRDs) and\n  `charts/crds/files/crds.bz2` — regenerated, never hand-edited\n- `charts/kube-prometheus-stack/UPGRADE.md` — new section\n- `charts/kube-prometheus-stack/templates/prometheus-operator/clusterrole.yaml`\n  — only if the operator's RBAC actually changed (see step 4)\n\n## Procedure\n\n### 1. Find the target version & branch\n\n```bash\n# Latest non-prerelease operator tag\ncurl -s https://api.github.com/repos/prometheus-operator/prometheus-operator/releases/latest | jq -r .tag_name\ngit checkout -b kube-prometheus-stack-bump-operator-<vX.Y.Z> upstream/main\n```\n\nAlways branch off a fresh `upstream/main` so the PR diff is just the bump.\n\n### 2. Bump Chart.yaml\n\nSet `appVersion` to the new `vX.Y.Z`. Bump the chart `version` following the\nprecedent of the previous bump: historically a **minor** operator bump\n(e.g. `v0.91.0 → v0.92.0`) is released as a **major** chart bump\n(e.g. `86.x → 87.0.0`). Confirm the convention against the last bump PR.\n\n### 3. Regenerate CRDs\n\n`hack/update_crds.sh` reads `appVersion` from `Chart.yaml`, so bump Chart.yaml\n**first**, then:\n\n```bash\nbash charts/kube-prometheus-stack/hack/update_crds.sh\n```\n\nThis downloads the 10 CRDs from\n`prometheus-operator/.../<appVersion>/example/prometheus-operator-crd/` and\nrebuilds `charts/crds/files/crds.bz2`.\n\n**Check for new CRD kinds** — if the operator added a CRD, the `FILES` array in\n`update_crds.sh` (and the `crds` subchart) must be extended:\n\n```bash\ndiff \\\n  <(curl -s \"https://api.github.com/repos/prometheus-operator/prometheus-operator/contents/example/prometheus-operator-crd?ref=<OLD>\" | jq -r '.[].name' | sort) \\\n  <(curl -s \"https://api.github.com/repos/prometheus-operator/prometheus-operator/contents/example/prometheus-operator-crd?ref=<NEW>\" | jq -r '.[].name' | sort)\n```\n\n### 4. Check RBAC\n\nThe chart's operator `ClusterRole` is maintained by hand, so confirm whether the\noperator's required RBAC changed between versions:\n\n```bash\nf=example/rbac/prometheus-operator/prometheus-operator-cluster-role.yaml\ndiff \\\n  <(curl -s \"https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/<OLD>/$f\") \\\n  <(curl -s \"https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/<NEW>/$f\")\n```\n\nA diff in only the `app.kubernetes.io/version` label = **no change needed**.\nAny new/removed `rules` entry = update\n`templates/prometheus-operator/clusterrole.yaml` to match. Most patch/minor\noperator bumps need no RBAC change.\n\n### 5. Check for new spec fields\n\nNew CRD properties arrive silently with the regenerated CRDs — the chart renders\neach `*Spec` field explicitly, so a field nobody wires up stays unreachable\nexcept through `additionalConfig`. Diff the regenerated CRDs against the\ncommitted ones to find what the release added:\n\n```bash\ncd charts/kube-prometheus-stack/charts/crds/crds\nfor f in crd-*.yaml; do python3 - \"$f\" <<'PY'\nimport subprocess, sys, yaml\nf = sys.argv[1]\n# crd-alertmanagerconfigs.yaml contains a bare `=`, which SafeLoader rejects\nyaml.SafeLoader.add_constructor(\"tag:yaml.org,2002:value\", lambda l, n: l.construct_scalar(n))\ndef paths(doc, prefix=\"\"):\n    out = set()\n    for k, v in (doc.get(\"properties\") or {}).items():\n        out.add(prefix + k)\n        out |= paths(v, prefix + k + \".\")\n    return out\ndef spec(doc):\n    return doc[\"spec\"][\"versions\"][0][\"schema\"][\"openAPIV3Schema\"][\"properties\"][\"spec\"]\nold = yaml.safe_load(subprocess.run([\"git\", \"show\", f\"HEAD:./{f}\"], capture_output=True, text=True).stdout)\nadded = paths(spec(yaml.safe_load(open(f)))) - paths(spec(old))\nif added:\n    print(f, *sorted(added), sep=\"\\n  \")\nPY\ndone\n```\n\nThen check which of the added paths the chart can already reach: grep the\nrendering template for `.Values.<component>Spec.<field>`. A field passed through\n`toYaml`/`with` covers its whole subtree; one rendered key by key (`tsdb`,\n`thanos`) only covers the sub-keys it names.\n\n**Exposing them is a separate PR.** Keep the bump to the file set above — a\nfollow-up adds the values, the template lines and helm-unittest coverage with a\nminor chart bump. The same sweep run against the full CRD (not just the diff)\nfinds older gaps too; see #7270 and #7272 for both shapes.\n\n### 6. Update UPGRADE.md\n\nPrepend a `## From <old-major>.x to <new-major>.x` section. Copy the previous\nsection's wording and the 10 `kubectl apply --server-side -f .../<NEW>/...`\nCRD commands, swapping the version.\n\n### 7. Validate\n\n```bash\ncd charts/kube-prometheus-stack\nhelm dependency build .        # required, or lint nil-pointers on subchart values\nhelm lint .\nhelm template t . | grep 'prometheus-operator:'   # must show the new vX.Y.Z\n```\n\n> CRDs live in the Helm-native `charts/crds/crds/` directory and are **not**\n> rendered by `helm template` — that is expected. The `crds.bz2` only feeds the\n> optional `crds.upgradeJob`.\n\n### 8. Commit & PR\n\n- Sign off (DCO) — see `CONTRIBUTING.md#sign-off-your-work`.\n- Title: `[kube-prometheus-stack] Bump prometheus-operator to vX.Y.Z`.\n- On review updates, add new commits — **do not squash** (the PR is squashed on\n  merge).\n- Fill the PR template; tick DCO + Chart Version bumped + title-starts-with-chart.\n",".agents/skills/helm-chart-test/SKILL.md":"---\nname: helm-chart-test\ndescription: Plan, write, and validate helm-unittest tests for a chart. Discovers chart structure, maps coverage gaps, and applies repository helm-unittest conventions.\nuser_invocable: true\n---\n\n# /helm-chart-test [chart] [component]\n\nUse this skill whenever the user asks to add, expand, fix, or review helm-unittest coverage for a chart, or when a chart feature change needs matching rendered-manifest tests.\n\n## Argument Handling\n\n**During feature implementation**, infer the chart and component from the files being changed or from the requested feature. Add or update focused tests for the affected rendered behavior without pausing for broad coverage analysis or scoping questions, unless the requested behavior is ambiguous.\n\n**If no arguments are provided for a standalone test task**, ask the user which chart they want to work on, then proceed as if they provided just the chart name.\n\n**If only `<chart>` is provided for a standalone coverage audit**, run the full discovery and coverage analysis below before asking any questions.\n\n**If `<chart> <component>` is provided for a standalone test task**, inspect that component and choose the relevant existing or new test files. Ask scoping questions only when the requested coverage depth or target templates cannot be inferred.\n\n## Feature Implementation Mode\n\nWhen this skill is used as part of implementing a chart feature, do not stop after planning or ask the user to choose a component. Instead:\n\n1. Identify the affected chart from `charts/<chart>/...`.\n2. Identify affected templates, helpers, and values from the feature diff or requested change.\n3. Read existing nearby tests and mirror their style.\n4. Add or update focused tests for the new or changed rendered behavior.\n5. Cover important enabled/disabled branches, value propagation, selectors, labels, annotations, containers, volumes, and service wiring touched by the feature.\n6. Run the relevant `make helm-unittest HELM_CHART=<chart-name>` command.\n\nAsk the user only when there are multiple plausible feature semantics or when the chart/component cannot be determined from local context.\n\n## Discovery and Coverage Analysis\n\nWork through these steps silently. Produce a single structured report at the end.\n\n### 1. Understand the Chart Structure\n\n- Read `charts/<chart>/Chart.yaml` and note the chart type, version, kubeVersion, and dependencies.\n- Read the top level of `charts/<chart>/values.yaml` to understand major configuration axes, deployment modes, and component enable flags.\n- List `charts/<chart>/templates/**`.\n- Identify component groups. Subdirectories under `templates/` are natural groups. If the chart has flat templates, treat the whole chart as one component.\n- Read `_helpers.tpl` and any other `_*.tpl` files before testing templates that call helpers.\n\n### 2. Map Existing Test Coverage\n\n- List `charts/<chart>/tests/**`.\n- For each component group, count:\n  - renderable templates, excluding `_*.tpl` helper/partial files\n  - corresponding test files in `charts/<chart>/tests/<component>/`\n- Check whether existing tests exercise the relevant branches, not just whether a file exists.\n\n### 3. Assess Complexity\n\nDetermine whether the chart is **simple** or **complex**.\n\n- **Simple**: flat templates, no deployment modes, fewer than 10 renderable templates.\n- **Complex**: subdirectories, deployment modes, major conditional rendering, or more than 10 renderable templates.\n\nFor a simple chart, present a single coverage table and recommend whether to proceed with the whole chart at once.\n\nFor a complex chart, group templates into logical work units and recommend a starting component.\n\n### 4. Present the Coverage Report\n\nUse this format:\n\n```md\n## <chart> - Test Coverage Analysis\n\n| Component | Renderable templates | Test files | Coverage |\n|---|---:|---:|---|\n| core / root-level | N | N | None / Partial / Good |\n| gateway | N | N | None / Partial / Good |\n| ingester | N | N | None / Partial / Good |\n\n### Notes\n- <important observations about deployment modes, required values, lookup usage, or test complexity>\n\n### Suggested starting point\n<recommend the lowest-risk, highest-value component and explain why>\n\nRecommended next test target: <component or whole chart>\n```\n\nFor standalone coverage audits, wait for the user to choose a component before writing tests. For feature implementation, proceed with focused tests for the component touched by the feature.\n\n## Scoping Questions\n\nFor standalone test-expansion tasks where scope cannot be inferred, ask:\n\n1. Scope within the component: all templates, or specific templates?\n2. Existing tests: extend partial tests, or add new test files alongside them?\n3. Coverage depth: happy path only, or full branch coverage for every significant `if` / `with` / `range`?\n4. Known gotchas: deployment modes, required values, lookup behavior, subchart values, or compatibility constraints?\n\nAfter the user answers, summarize the agreed scope in one short paragraph, then begin writing tests. Skip these questions when implementing a specific feature and the affected behavior is clear from the request or diff.\n\n## helm-unittest Overview\n\nTests are YAML files in `charts/<chart-name>/tests/` that validate rendered Kubernetes manifests. Each test renders templates with specified values and asserts on the output.\n\nEach `tests[].it` case renders independently with that case's value inputs. Keep tests focused and deterministic: one behavior per test, explicit value overrides, and scoped assertions.\n\n### Test File Structure\n\n```yaml\n# $schema: https://raw.githubusercontent.com/helm-unittest/helm-unittest/refs/heads/main/schema/helm-testsuite.json\nsuite: <descriptive suite name>\nvalues:\n  - ../ci/<values-file>.yaml\nset:\n  key.nested: value\ntemplates:\n  - templates/<path-to-template>.yaml\ntests:\n  - it: <test case description>\n    values:\n      - ./values/<scenario>.yaml\n    set:\n      key.nested: value\n    documentSelector:\n      path: metadata.name\n      value: RELEASE-NAME-myapp\n    asserts:\n      - isKind:\n          of: Deployment\n      - equal:\n          path: metadata.name\n          value: RELEASE-NAME-myapp\n      - contains:\n          path: spec.template.spec.containers[0].env\n          content:\n            name: MY_VAR\n            value: my-value\n```\n\n### Scope, Precedence, and Targeting\n\n- Value precedence: chart `values.yaml` < suite `values` < suite `set` < test `values` < test `set`.\n- Template scope precedence: suite `templates` can be narrowed by test `template` / `templates`, then by assertion-level `template`.\n- Document targeting precedence: assertion `documentSelector` / `documentIndex` overrides test-level selector/index.\n- Use `documentSelector` for multi-document templates instead of brittle numeric `documentIndex` when possible.\n- `hasDocuments` ignores selectors by default; set `filterAware: true` to count only selector/index-filtered documents.\n\n### Suite and Test Options\n\n- `release`: exercise behavior that depends on `.Release` (`name`, `namespace`, `revision`, `upgrade`).\n- `capabilities`: pin Kubernetes versions/APIs for branches guarded by `.Capabilities.*`.\n- `chart`: override `.Chart.version` / `.Chart.appVersion` when template output depends on them.\n- `excludeTemplates`: narrow broad template globs to avoid unrelated documents in a suite.\n- `skip`: only for temporary or unreleased behavior; prefer active assertions over skipped tests.\n- `postRenderer`: use only when chart behavior explicitly depends on post-render transforms.\n\n## Testing `lookup` with `kubernetesProvider`\n\nUse `kubernetesProvider` whenever templates call `lookup`; without it, `lookup` returns empty and branch coverage is incomplete.\n\n- Register API kinds in `scheme` using `\"<group>/<version>/<Kind>\"` or `\"v1/<Kind>\"` for core APIs.\n- Each scheme entry must define `gvr` (`group` optional for core APIs, plus `version`, `resource`) and `namespaced`.\n- Provide fixture resources in `objects`.\n- Test-level `kubernetesProvider.objects` can add scenario-specific fixtures without rewriting suite-wide defaults.\n\n```yaml\ntemplates:\n  - templates/lookup.yaml\nkubernetesProvider:\n  scheme:\n    \"v1/Namespace\":\n      gvr:\n        version: \"v1\"\n        resource: \"namespaces\"\n      namespaced: false\n    \"v1/Pod\":\n      gvr:\n        version: \"v1\"\n        resource: \"pods\"\n      namespaced: true\n    \"networking.k8s.io/v1/Ingress\":\n      gvr:\n        group: \"networking.k8s.io\"\n        version: \"v1\"\n        resource: \"ingresses\"\n      namespaced: true\n  objects:\n    - kind: Pod\n      apiVersion: v1\n      metadata:\n        name: exists\n        namespace: default\ntests:\n  - it: should find existing pod through lookup\n    asserts:\n      - isNotNullOrEmpty:\n          path: pod_exists\n      - equal:\n          path: pod_exists.metadata.name\n          value: exists\n  - it: should find test-level object through lookup\n    kubernetesProvider:\n      objects:\n        - kind: Pod\n          apiVersion: v1\n          metadata:\n            name: not-exists\n            namespace: default\n    asserts:\n      - isNotNullOrEmpty:\n          path: pod_not_exists\n      - equal:\n          path: pod_not_exists.metadata.name\n          value: not-exists\n```\n\n## Assertion Guidance\n\n| Assertion | Purpose |\n|---|---|\n| `equal` | Exact match at JSON path |\n| `notEqual` | Value differs from expected |\n| `matchRegex` | Regular expression match on string value |\n| `exists` | Path exists in rendered output |\n| `notExists` | Path is absent from rendered output |\n| `isEmpty` / `isNotEmpty` | Path is empty or not empty |\n| `isNullOrEmpty` / `isNotNullOrEmpty` | Path is null/empty or present with content |\n| `isKind` | Kubernetes resource kind check |\n| `isAPIVersion` | API version check |\n| `contains` | Array/map contains entry |\n| `notContains` | Array/map does not contain entry |\n| `hasDocuments` | Number of YAML documents rendered |\n| `matchSnapshot` | Snapshot testing |\n| `failedTemplate` | Template should fail to render |\n| `notFailedTemplate` | Template should render successfully |\n| `isSubset` | Rendered output is a superset of expected |\n| `lengthEqual` | Array/map length equals expected count |\n\nUse antonym assertions (`notEqual`, `notContains`, etc.) instead of relying on `not: true` unless that is clearer.\n\nPrefer `equal`, `contains`, and specific negative assertions over broad `exists` checks. Specific assertions catch regressions.\n\n### Assertion Scoping Patterns\n\n```yaml\n  - it: targets a single Deployment by name\n    templates:\n      - templates/deployment.yaml\n      - templates/image-renderer-deployment.yaml\n    asserts:\n      - equal:\n          path: spec.replicas\n          value: 1\n        documentSelector:\n          path: metadata.name\n          value: RELEASE-NAME-grafana\n```\n\n```yaml\n  - it: counts only selected docs\n    template: templates/extra-manifests.yaml\n    documentSelector:\n      path: kind\n      value: ConfigMap\n      matchMany: true\n    asserts:\n      - hasDocuments:\n          count: 2\n          filterAware: true\n```\n\n### Multi-Template Safety\n\nIf a suite includes workload templates plus `config.yaml`, set `template` on every assertion unless the test intentionally targets all templates.\n\nPut `template` at the assertion root, not inside assertion parameters.\n\nWrong:\n\n```yaml\n      - notContains:\n          template: backend/statefulset.yaml\n          path: spec.template.spec.containers\n          content:\n            name: loki-sc-rules\n```\n\nCorrect:\n\n```yaml\n      - template: backend/statefulset.yaml\n        notContains:\n          path: spec.template.spec.containers\n          content:\n            name: loki-sc-rules\n```\n\n### Path and jsonPath Guidance\n\n- Prefer precise paths over broad existence checks.\n- When map keys contain dots or slashes, use jsonPath bracket syntax.\n- Keep escaping consistent to avoid false negatives.\n\n```yaml\n  - equal:\n      path: metadata.annotations[\"kubernetes.io/ingress.class\"]\n      value: nginx\n```\n\n### Conditional Rendering Tests\n\n```yaml\n  - it: should not render when disabled\n    set:\n      component.enabled: false\n    asserts:\n      - hasDocuments:\n          count: 0\n```\n\n### Testing with Release Values\n\n```yaml\n  - it: should use release name in labels\n    release:\n      name: my-release\n      namespace: my-namespace\n    asserts:\n      - equal:\n          path: metadata.namespace\n          value: my-namespace\n```\n\n## Test File Organization\n\nMirror the template directory structure:\n\n```text\ncharts/<chart>/tests/\n  deployment_test.yaml\n  service_test.yaml\n  ingester/\n    statefulset_test.yaml\n  compactor/\n    deployment_test.yaml\n```\n\nTest filenames must end with `.yaml`. This repository configures helm-unittest with `--file 'tests/**/*.yaml'`, so any `.yaml` filename is valid. `<template>_test.yaml` is preferred.\n\n## Writing Workflow\n\n1. Read the template being tested. Understand every conditional, value reference, helper call, and document emitted.\n2. Read `_helpers.tpl` and any other helper partials used by the template.\n3. Read `values.yaml` to understand defaults and the full value schema.\n4. Map render targets: determine whether the template emits zero, one, or many documents and which selector is stable.\n5. Write tests for default rendering, significant conditional branches, selector behavior, multi-template scoping, and edge cases.\n6. Run the tests.\n7. Fix failures by adjusting assertions to match actual rendered output.\n8. Repeat until the test file passes.\n\n## Running Tests\n\nRun all charts:\n\n```bash\nmake helm-unittest\n```\n\nRun tests for one chart:\n\n```bash\nmake helm-unittest HELM_CHART=<chart-name>\n```\n\nRun one test file:\n\n```bash\nmake helm-unittest HELM_CHART=<chart-name> HELM_UNITTEST_FILE='tests/<subdir>/<file>_test.yaml'\n```\n\n## Rules\n\n- Only create or edit `.yaml` files under `charts/*/tests/` when this skill is being used specifically to write tests.\n- Do not modify templates, `values.yaml`, `Chart.yaml`, or non-test files as part of a test-writing task unless the user explicitly expands the scope.\n- Never run destructive shell commands.\n- Use `RELEASE-NAME` as the default release name in assertions.\n- Always set deployment-mode-style flags explicitly. Do not rely on defaults when a chart has conditional rendering modes.\n- When a template has subchart dependencies, use `set` to provide required subchart values.\n- Always run relevant helm-unittest commands after writing tests.\n- If a test run reveals the template does not render with default values, inspect `values.yaml` and adjust the test setup.\n- Prefer `documentSelector` over hardcoded `documentIndex` for templates that can reorder output.\n- Use `hasDocuments.filterAware: true` when asserting counts under selector/index filtering.\n- Use `template` / `templates` at test or assertion level to prevent cross-template assertion bleed.\n- For negative paths, assert absence with `notExists` or `notContains`.\n"},"files":{".agents/skills/helm-values-schema/SKILL.md":"---\nname: helm-values-schema\ndescription: Maintain values.schema.json for Helm charts that use helm-values-schema-json annotations in values.yaml.\nuser_invocable: true\n---\n\n# /helm-values-schema [chart]\n\nUse this skill when the user asks to add, change, review, or regenerate a Helm chart `values.schema.json`, or when a chart feature changes `values.yaml` in a chart that uses schema annotations.\n\n## Detection\n\nA chart uses `helm-values-schema-json` if `charts/<chart>/values.yaml` contains either:\n\n- `# @schema` comments\n- a top-level schema reference such as `# $schema: ./values.schema.json`\n\nWhen a chart uses this flow, changes to `values.yaml` must keep schema annotations and `values.schema.json` in sync.\n\n## Documentation\n\nPrefer Context7 for current `helm-values-schema-json` docs when available.\n\nUpstream documentation:\n\n```text\nhttps://github.com/losisin/helm-values-schema-json/blob/main/docs/README.md\n```\n\n## Compatibility\n\nHelm validates chart values with JSON Schema draft-07. Keep generated schemas compatible with draft-07 even if external schema tooling supports newer drafts.\n\n## Workflow\n\n1. Read `charts/<chart>/values.yaml`.\n2. Check whether `# @schema` annotations or `# $schema: ./values.schema.json` are present.\n3. If changing or adding values, preserve nearby annotations and add annotations when inferred schema would be wrong or too loose.\n4. Preserve helm-docs comments. When a field has both `# @schema` and helm-docs `# --` comments, `# @schema` comments must be above the helm-docs description comments.\n5. Regenerate `values.schema.json`.\n6. Review the schema diff for only intentional changes.\n7. Ensure values changes also have helm-unittest coverage for rendered behavior where applicable.\n\n## helm-docs Integration\n\n`helm-values-schema-json` supports using descriptions from `helm-docs` comments since v2.0.0, but only when enabled with `--use-helm-docs`.\n\nExample:\n\n```bash\nhelm schema --use-helm-docs\n```\n\n```yaml\n# -- My description\nfullnameOverride: bar\n```\n\nGenerates:\n\n```json\n{\n  \"fullnameOverride\": {\n    \"description\": \"My description\",\n    \"type\": \"string\"\n  }\n}\n```\n\n### Unsupported helm-docs Features\n\nThe schema plugin does not support helm-docs-specific properties such as:\n\n- `# @default --`\n- `# @section --`\n\nIt also does not support detached helm-docs comments. Comments must be directly above the property or inline in a supported form.\n\nSupported:\n\n```yaml\n# fullnameOverride -- This works\nfullnameOverride: bar\n```\n\nNot supported by the schema plugin:\n\n```yaml\nfullnameOverride: bar\n\n# fullnameOverride -- This does not work for schema generation.\nfullnameOverride: bar\n```\n\nHelm-docs itself does not understand `# @schema` comments. When both `# @schema` and helm-docs comments are above a field, put `# @schema` first so schema annotations are not included in the generated description. Treat the inverse order as invalid: helm-docs will include the schema annotation text in the description.\n\nGood:\n\n```yaml\n# @schema maxLength:10\n# -- My awesome nameOverride description\nnameOverride: \"myapp\"\n```\n\nBad:\n\n```yaml\n# -- My awesome nameOverride description\n# @schema maxLength:10\nnameOverride: \"myapp\"\n```\n\n## Annotation Placement\n\n`# @schema` annotations may be placed inline, on the line above a field, or in specific cases below a block. Preserve the surrounding style already used in the chart, except when the existing style conflicts with helm-docs ordering. If a value has a helm-docs `# --` description, any standalone `# @schema` comments for that value must be above the `# --` comment, never between the helm-docs comment and the value.\n\nExamples:\n\n```yaml\nfullnameOverride: \"myapp\" # @schema maxLength:10;pattern:^[a-z]+$\n\n# @schema maxLength:10;pattern:^[a-z]+$\nnameOverride: \"myapp\"\n\n# @schema maxLength:10\n# -- My awesome nameOverride description\nnameOverride: \"myapp\"\n\n# Invalid with helm-docs: the schema annotation becomes part of the description.\n# -- My awesome nameOverride description\n# @schema maxLength:10\nnameOverride: \"myapp\"\n\nresources:\n  limits: {}\n  requests: {}\n# @schema additionalProperties:false\n```\n\nMultiple schema annotations can be separated with semicolons.\n\n## Commands\n\nFor Loki, use the repository target:\n\n```bash\nmake helm-schema HELM_CHART=loki\n```\n\nThe underlying command currently runs:\n\n```bash\nhelm schema --config .github/linters/.schema.yaml -f charts/loki/values.yaml -o charts/loki/values.schema.json\n```\n\nIf adding schema generation for another chart, follow the chart's local Makefile or CI pattern instead of inventing a one-off command.\n\n## Rules\n\n- Do not hand-edit `values.schema.json` when it can be regenerated.\n- Do not remove existing `# @schema` annotations unless the associated value is removed.\n- Keep schema annotations as close as possible to the value they describe.\n- Keep `# @schema` comments above helm-docs `# --` comments. Never add a standalone `# @schema` comment below a helm-docs description comment for the same value.\n- Include regenerated `values.schema.json` in the change.\n- Values changes that affect rendered manifests should also be covered by helm-unittest tests.\n","AGENTS.md":"# Instructions for AI Agents\n\nThe following guidelines apply to all files in this repository.\n\n## Repository Overview\n\nThis is the **Prometheus Community Helm Charts** repository — a collection of Helm charts for Prometheus ecosystem components. Charts are published to both a Helm repository (`prometheus-community`) and as OCI artifacts on `ghcr.io`.\n\n## Charts\n\nAll charts live under `charts/` with a subfolder for each chart.  The subfolder names must match the chart name as described in the Chart.yaml file `.name`.\n\nEach chart follows standard Helm structure (`Chart.yaml`, `values.yaml`, `templates/`). Some charts will organize components into subdirectories (e.g., `templates/grafana/`, `templates/prometheus/`, `templates/alertmanager/` in `kube-prometheus-stack`).\n\n## Feature Implementation Workflow\n\nMost agent tasks in this repository are chart feature changes. For these tasks:\n\n1. Identify the affected chart under `charts/<chart>/` and keep changes scoped to that chart.\n2. Read the relevant `Chart.yaml`, `values.yaml`, templates, helpers, and existing tests before editing.\n3. Implement the feature using the chart's existing template style and values structure.\n4. If `values.yaml` changes in a schema-enabled chart, update schema annotations and regenerate `values.schema.json`.\n5. Add or update focused helm-unittest coverage for the rendered behavior controlled by the feature.\n6. Bump the chart version in `Chart.yaml` according to SemVer.\n7. Run the relevant validation commands, normally `helm unittest --strict --file 'unittests/**/*.yaml' charts/<chart-name>` and any required schema generation command.\n\nAsk the user for clarification only when the intended chart, feature behavior, or compatibility impact cannot be inferred from the request and local context.\n\n## Values Schema\n\nSome charts generate `values.schema.json` from `values.yaml` using `helm-values-schema-json`. A chart uses this flow if `values.yaml` contains `# @schema` comments or a top-level `# $schema: ./values.schema.json` comment. Upstream documentation lives at https://github.com/losisin/helm-values-schema-json/blob/main/docs/README.md; use Context7 for current docs when available.\n\nHelm validates chart values with JSON Schema draft-07. Keep generated schemas compatible with draft-07 even if external schema tooling supports newer drafts.\n\nWhen changing `values.yaml` in a schema-enabled chart:\n\n- Use the `helm-values-schema` skill for detailed schema annotation and regeneration rules.\n- Preserve and update nearby `# @schema` annotations.\n- Add `# @schema` annotations when inferred schema types would be wrong or too loose.\n- Keep `# @schema` comments before helm-docs comments (`# -- ...`) when both are present.\n- Regenerate `values.schema.json` with `helm schema` from the chart directory and include it in the change.\n- Add or update helm-unittest coverage for rendered behavior controlled by the changed values.\n\n## pre-commit testing\n\n### helm-unittests\n\nPull Requests against this repository require that all charts which implement helm-unittests(https://github.com/helm-unittest/helm-unittest) must pass all of their unittests. CI runs them as an `additional-commands` entry of `ct lint` (see `.github/linters/ct.yaml`). The same command run from the repository root:\n\n```bash\nhelm unittest --strict --file 'unittests/**/*.yaml' charts/<chart-name>\n```\n\n### per-chart lint scripts\n\nA chart may carry a `ci/lint.sh`, which `ct lint` runs in addition to the unittests. `kube-prometheus-stack` uses it to verify that the generated CRDs, rules and dashboards are in sync, so changes there have to be produced by the scripts under `hack/` rather than edited in place.\n\n## Contributing Conventions\n\n- **One chart per PR**: CI enforces that PRs only change a single chart.\n- **PR title format**: Must start with `[chart-name] ` (e.g., `[grafana] Add new feature`).\n- **Version bumps**: Every chart change (excluding files listed in `.helmignore`) requires a SemVer version bump in `Chart.yaml`. Major bumps for breaking changes.\n- **DCO sign-off**: Commits must include `Signed-off-by` line (`git commit -s`).\n- **Squash merge only**: The repository only allows squash merges.\n- **Generated files**: `.github/CODEOWNERS`, `MAINTAINERS.md` and `.github/advanced-issue-labeler.yml` are generated from `charts/` by `scripts/generate-codeowners.sh`, `scripts/generate-maintainers.sh` and `scripts/generate-labeler.sh`. Do not edit them directly.\n- **Minimum Kubernetes version**: Charts that declare `kubeVersion` in `Chart.yaml` use a `>=` range, and the value differs per chart (`>=1.25.0-0` for `kube-prometheus-stack`, lower elsewhere). Most charts declare none at all. Match the chart you are editing instead of assuming a repository-wide floor.\n\n## Dependency Management\n\nRenovate manages all dependency updates.\n",".github/copilot-instructions.md":"# GitHub Copilot Instructions\n\nFollow the repository-wide agent guidance in `AGENTS.md`. This repository contains Helm charts for Prometheus ecosystem components.\n\nMost tasks are Helm chart feature changes. When changing a chart:\n\n- Work within a single chart under `charts/<chart>/`.\n- Read `Chart.yaml`, `values.yaml`, relevant templates, helpers, and existing tests before editing.\n- Follow existing chart patterns before adding new structure.\n- Update `values.yaml`, templates, tests, and generated schema artifacts together when a new value changes rendered behavior.\n- If `values.yaml` contains `# @schema` comments or `# $schema: ./values.schema.json`, follow the `helm-values-schema` skill guidance and regenerate `values.schema.json`.\n- Add or update helm-unittest coverage for rendered behavior changed by templates or values.\n- Run `helm unittest --strict --file 'unittests/**/*.yaml' charts/<chart-name>` for charts with helm-unittest coverage.\n- Bump the chart version in `Chart.yaml` for chart changes not ignored by `.helmignore`.\n- Do not edit generated ownership files such as `.github/CODEOWNERS` or `MAINTAINERS.md` directly.\n",".agents/skills/bump-prometheus-operator/SKILL.md":"---\nname: bump-prometheus-operator\ndescription: >-\n  Bump the prometheus-operator version shipped by the kube-prometheus-stack\n  chart. Use when a new prometheus-operator/prometheus-operator release is out\n  and the chart's appVersion needs to follow it: syncs CRDs, checks for new CRD\n  kinds, RBAC changes and newly added spec fields, bumps the chart version,\n  updates UPGRADE.md, and opens a PR. Triggers on \"bump prometheus-operator\",\n  \"update kube-prometheus-stack to the latest operator\", \"sync operator CRDs\".\n---\n\n# Bump prometheus-operator in kube-prometheus-stack\n\nPromotes the `appVersion` of `charts/kube-prometheus-stack` to a new\n`prometheus-operator/prometheus-operator` release and brings everything that\ntravels with the operator (CRDs, RBAC, upgrade notes) along with it.\n\n## Scope of an operator bump\n\nThe operator version is the chart's `appVersion`. A bump touches a small,\nfixed set of files — mirror the most recent merged bump PR (search\n`git log --oneline -S \"appVersion: v\" -- charts/kube-prometheus-stack/Chart.yaml`)\nrather than improvising:\n\n- `charts/kube-prometheus-stack/Chart.yaml` — `appVersion` + chart `version`\n- `charts/kube-prometheus-stack/charts/crds/crds/crd-*.yaml` (10 CRDs) and\n  `charts/crds/files/crds.bz2` — regenerated, never hand-edited\n- `charts/kube-prometheus-stack/UPGRADE.md` — new section\n- `charts/kube-prometheus-stack/templates/prometheus-operator/clusterrole.yaml`\n  — only if the operator's RBAC actually changed (see step 4)\n\n## Procedure\n\n### 1. Find the target version & branch\n\n```bash\n# Latest non-prerelease operator tag\ncurl -s https://api.github.com/repos/prometheus-operator/prometheus-operator/releases/latest | jq -r .tag_name\ngit checkout -b kube-prometheus-stack-bump-operator-<vX.Y.Z> upstream/main\n```\n\nAlways branch off a fresh `upstream/main` so the PR diff is just the bump.\n\n### 2. Bump Chart.yaml\n\nSet `appVersion` to the new `vX.Y.Z`. Bump the chart `version` following the\nprecedent of the previous bump: historically a **minor** operator bump\n(e.g. `v0.91.0 → v0.92.0`) is released as a **major** chart bump\n(e.g. `86.x → 87.0.0`). Confirm the convention against the last bump PR.\n\n### 3. Regenerate CRDs\n\n`hack/update_crds.sh` reads `appVersion` from `Chart.yaml`, so bump Chart.yaml\n**first**, then:\n\n```bash\nbash charts/kube-prometheus-stack/hack/update_crds.sh\n```\n\nThis downloads the 10 CRDs from\n`prometheus-operator/.../<appVersion>/example/prometheus-operator-crd/` and\nrebuilds `charts/crds/files/crds.bz2`.\n\n**Check for new CRD kinds** — if the operator added a CRD, the `FILES` array in\n`update_crds.sh` (and the `crds` subchart) must be extended:\n\n```bash\ndiff \\\n  <(curl -s \"https://api.github.com/repos/prometheus-operator/prometheus-operator/contents/example/prometheus-operator-crd?ref=<OLD>\" | jq -r '.[].name' | sort) \\\n  <(curl -s \"https://api.github.com/repos/prometheus-operator/prometheus-operator/contents/example/prometheus-operator-crd?ref=<NEW>\" | jq -r '.[].name' | sort)\n```\n\n### 4. Check RBAC\n\nThe chart's operator `ClusterRole` is maintained by hand, so confirm whether the\noperator's required RBAC changed between versions:\n\n```bash\nf=example/rbac/prometheus-operator/prometheus-operator-cluster-role.yaml\ndiff \\\n  <(curl -s \"https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/<OLD>/$f\") \\\n  <(curl -s \"https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/<NEW>/$f\")\n```\n\nA diff in only the `app.kubernetes.io/version` label = **no change needed**.\nAny new/removed `rules` entry = update\n`templates/prometheus-operator/clusterrole.yaml` to match. Most patch/minor\noperator bumps need no RBAC change.\n\n### 5. Check for new spec fields\n\nNew CRD properties arrive silently with the regenerated CRDs — the chart renders\neach `*Spec` field explicitly, so a field nobody wires up stays unreachable\nexcept through `additionalConfig`. Diff the regenerated CRDs against the\ncommitted ones to find what the release added:\n\n```bash\ncd charts/kube-prometheus-stack/charts/crds/crds\nfor f in crd-*.yaml; do python3 - \"$f\" <<'PY'\nimport subprocess, sys, yaml\nf = sys.argv[1]\n# crd-alertmanagerconfigs.yaml contains a bare `=`, which SafeLoader rejects\nyaml.SafeLoader.add_constructor(\"tag:yaml.org,2002:value\", lambda l, n: l.construct_scalar(n))\ndef paths(doc, prefix=\"\"):\n    out = set()\n    for k, v in (doc.get(\"properties\") or {}).items():\n        out.add(prefix + k)\n        out |= paths(v, prefix + k + \".\")\n    return out\ndef spec(doc):\n    return doc[\"spec\"][\"versions\"][0][\"schema\"][\"openAPIV3Schema\"][\"properties\"][\"spec\"]\nold = yaml.safe_load(subprocess.run([\"git\", \"show\", f\"HEAD:./{f}\"], capture_output=True, text=True).stdout)\nadded = paths(spec(yaml.safe_load(open(f)))) - paths(spec(old))\nif added:\n    print(f, *sorted(added), sep=\"\\n  \")\nPY\ndone\n```\n\nThen check which of the added paths the chart can already reach: grep the\nrendering template for `.Values.<component>Spec.<field>`. A field passed through\n`toYaml`/`with` covers its whole subtree; one rendered key by key (`tsdb`,\n`thanos`) only covers the sub-keys it names.\n\n**Exposing them is a separate PR.** Keep the bump to the file set above — a\nfollow-up adds the values, the template lines and helm-unittest coverage with a\nminor chart bump. The same sweep run against the full CRD (not just the diff)\nfinds older gaps too; see #7270 and #7272 for both shapes.\n\n### 6. Update UPGRADE.md\n\nPrepend a `## From <old-major>.x to <new-major>.x` section. Copy the previous\nsection's wording and the 10 `kubectl apply --server-side -f .../<NEW>/...`\nCRD commands, swapping the version.\n\n### 7. Validate\n\n```bash\ncd charts/kube-prometheus-stack\nhelm dependency build .        # required, or lint nil-pointers on subchart values\nhelm lint .\nhelm template t . | grep 'prometheus-operator:'   # must show the new vX.Y.Z\n```\n\n> CRDs live in the Helm-native `charts/crds/crds/` directory and are **not**\n> rendered by `helm template` — that is expected. The `crds.bz2` only feeds the\n> optional `crds.upgradeJob`.\n\n### 8. Commit & PR\n\n- Sign off (DCO) — see `CONTRIBUTING.md#sign-off-your-work`.\n- Title: `[kube-prometheus-stack] Bump prometheus-operator to vX.Y.Z`.\n- On review updates, add new commits — **do not squash** (the PR is squashed on\n  merge).\n- Fill the PR template; tick DCO + Chart Version bumped + title-starts-with-chart.\n",".agents/skills/helm-chart-test/SKILL.md":"---\nname: helm-chart-test\ndescription: Plan, write, and validate helm-unittest tests for a chart. Discovers chart structure, maps coverage gaps, and applies repository helm-unittest conventions.\nuser_invocable: true\n---\n\n# /helm-chart-test [chart] [component]\n\nUse this skill whenever the user asks to add, expand, fix, or review helm-unittest coverage for a chart, or when a chart feature change needs matching rendered-manifest tests.\n\n## Argument Handling\n\n**During feature implementation**, infer the chart and component from the files being changed or from the requested feature. Add or update focused tests for the affected rendered behavior without pausing for broad coverage analysis or scoping questions, unless the requested behavior is ambiguous.\n\n**If no arguments are provided for a standalone test task**, ask the user which chart they want to work on, then proceed as if they provided just the chart name.\n\n**If only `<chart>` is provided for a standalone coverage audit**, run the full discovery and coverage analysis below before asking any questions.\n\n**If `<chart> <component>` is provided for a standalone test task**, inspect that component and choose the relevant existing or new test files. Ask scoping questions only when the requested coverage depth or target templates cannot be inferred.\n\n## Feature Implementation Mode\n\nWhen this skill is used as part of implementing a chart feature, do not stop after planning or ask the user to choose a component. Instead:\n\n1. Identify the affected chart from `charts/<chart>/...`.\n2. Identify affected templates, helpers, and values from the feature diff or requested change.\n3. Read existing nearby tests and mirror their style.\n4. Add or update focused tests for the new or changed rendered behavior.\n5. Cover important enabled/disabled branches, value propagation, selectors, labels, annotations, containers, volumes, and service wiring touched by the feature.\n6. Run the relevant `make helm-unittest HELM_CHART=<chart-name>` command.\n\nAsk the user only when there are multiple plausible feature semantics or when the chart/component cannot be determined from local context.\n\n## Discovery and Coverage Analysis\n\nWork through these steps silently. Produce a single structured report at the end.\n\n### 1. Understand the Chart Structure\n\n- Read `charts/<chart>/Chart.yaml` and note the chart type, version, kubeVersion, and dependencies.\n- Read the top level of `charts/<chart>/values.yaml` to understand major configuration axes, deployment modes, and component enable flags.\n- List `charts/<chart>/templates/**`.\n- Identify component groups. Subdirectories under `templates/` are natural groups. If the chart has flat templates, treat the whole chart as one component.\n- Read `_helpers.tpl` and any other `_*.tpl` files before testing templates that call helpers.\n\n### 2. Map Existing Test Coverage\n\n- List `charts/<chart>/tests/**`.\n- For each component group, count:\n  - renderable templates, excluding `_*.tpl` helper/partial files\n  - corresponding test files in `charts/<chart>/tests/<component>/`\n- Check whether existing tests exercise the relevant branches, not just whether a file exists.\n\n### 3. Assess Complexity\n\nDetermine whether the chart is **simple** or **complex**.\n\n- **Simple**: flat templates, no deployment modes, fewer than 10 renderable templates.\n- **Complex**: subdirectories, deployment modes, major conditional rendering, or more than 10 renderable templates.\n\nFor a simple chart, present a single coverage table and recommend whether to proceed with the whole chart at once.\n\nFor a complex chart, group templates into logical work units and recommend a starting component.\n\n### 4. Present the Coverage Report\n\nUse this format:\n\n```md\n## <chart> - Test Coverage Analysis\n\n| Component | Renderable templates | Test files | Coverage |\n|---|---:|---:|---|\n| core / root-level | N | N | None / Partial / Good |\n| gateway | N | N | None / Partial / Good |\n| ingester | N | N | None / Partial / Good |\n\n### Notes\n- <important observations about deployment modes, required values, lookup usage, or test complexity>\n\n### Suggested starting point\n<recommend the lowest-risk, highest-value component and explain why>\n\nRecommended next test target: <component or whole chart>\n```\n\nFor standalone coverage audits, wait for the user to choose a component before writing tests. For feature implementation, proceed with focused tests for the component touched by the feature.\n\n## Scoping Questions\n\nFor standalone test-expansion tasks where scope cannot be inferred, ask:\n\n1. Scope within the component: all templates, or specific templates?\n2. Existing tests: extend partial tests, or add new test files alongside them?\n3. Coverage depth: happy path only, or full branch coverage for every significant `if` / `with` / `range`?\n4. Known gotchas: deployment modes, required values, lookup behavior, subchart values, or compatibility constraints?\n\nAfter the user answers, summarize the agreed scope in one short paragraph, then begin writing tests. Skip these questions when implementing a specific feature and the affected behavior is clear from the request or diff.\n\n## helm-unittest Overview\n\nTests are YAML files in `charts/<chart-name>/tests/` that validate rendered Kubernetes manifests. Each test renders templates with specified values and asserts on the output.\n\nEach `tests[].it` case renders independently with that case's value inputs. Keep tests focused and deterministic: one behavior per test, explicit value overrides, and scoped assertions.\n\n### Test File Structure\n\n```yaml\n# $schema: https://raw.githubusercontent.com/helm-unittest/helm-unittest/refs/heads/main/schema/helm-testsuite.json\nsuite: <descriptive suite name>\nvalues:\n  - ../ci/<values-file>.yaml\nset:\n  key.nested: value\ntemplates:\n  - templates/<path-to-template>.yaml\ntests:\n  - it: <test case description>\n    values:\n      - ./values/<scenario>.yaml\n    set:\n      key.nested: value\n    documentSelector:\n      path: metadata.name\n      value: RELEASE-NAME-myapp\n    asserts:\n      - isKind:\n          of: Deployment\n      - equal:\n          path: metadata.name\n          value: RELEASE-NAME-myapp\n      - contains:\n          path: spec.template.spec.containers[0].env\n          content:\n            name: MY_VAR\n            value: my-value\n```\n\n### Scope, Precedence, and Targeting\n\n- Value precedence: chart `values.yaml` < suite `values` < suite `set` < test `values` < test `set`.\n- Template scope precedence: suite `templates` can be narrowed by test `template` / `templates`, then by assertion-level `template`.\n- Document targeting precedence: assertion `documentSelector` / `documentIndex` overrides test-level selector/index.\n- Use `documentSelector` for multi-document templates instead of brittle numeric `documentIndex` when possible.\n- `hasDocuments` ignores selectors by default; set `filterAware: true` to count only selector/index-filtered documents.\n\n### Suite and Test Options\n\n- `release`: exercise behavior that depends on `.Release` (`name`, `namespace`, `revision`, `upgrade`).\n- `capabilities`: pin Kubernetes versions/APIs for branches guarded by `.Capabilities.*`.\n- `chart`: override `.Chart.version` / `.Chart.appVersion` when template output depends on them.\n- `excludeTemplates`: narrow broad template globs to avoid unrelated documents in a suite.\n- `skip`: only for temporary or unreleased behavior; prefer active assertions over skipped tests.\n- `postRenderer`: use only when chart behavior explicitly depends on post-render transforms.\n\n## Testing `lookup` with `kubernetesProvider`\n\nUse `kubernetesProvider` whenever templates call `lookup`; without it, `lookup` returns empty and branch coverage is incomplete.\n\n- Register API kinds in `scheme` using `\"<group>/<version>/<Kind>\"` or `\"v1/<Kind>\"` for core APIs.\n- Each scheme entry must define `gvr` (`group` optional for core APIs, plus `version`, `resource`) and `namespaced`.\n- Provide fixture resources in `objects`.\n- Test-level `kubernetesProvider.objects` can add scenario-specific fixtures without rewriting suite-wide defaults.\n\n```yaml\ntemplates:\n  - templates/lookup.yaml\nkubernetesProvider:\n  scheme:\n    \"v1/Namespace\":\n      gvr:\n        version: \"v1\"\n        resource: \"namespaces\"\n      namespaced: false\n    \"v1/Pod\":\n      gvr:\n        version: \"v1\"\n        resource: \"pods\"\n      namespaced: true\n    \"networking.k8s.io/v1/Ingress\":\n      gvr:\n        group: \"networking.k8s.io\"\n        version: \"v1\"\n        resource: \"ingresses\"\n      namespaced: true\n  objects:\n    - kind: Pod\n      apiVersion: v1\n      metadata:\n        name: exists\n        namespace: default\ntests:\n  - it: should find existing pod through lookup\n    asserts:\n      - isNotNullOrEmpty:\n          path: pod_exists\n      - equal:\n          path: pod_exists.metadata.name\n          value: exists\n  - it: should find test-level object through lookup\n    kubernetesProvider:\n      objects:\n        - kind: Pod\n          apiVersion: v1\n          metadata:\n            name: not-exists\n            namespace: default\n    asserts:\n      - isNotNullOrEmpty:\n          path: pod_not_exists\n      - equal:\n          path: pod_not_exists.metadata.name\n          value: not-exists\n```\n\n## Assertion Guidance\n\n| Assertion | Purpose |\n|---|---|\n| `equal` | Exact match at JSON path |\n| `notEqual` | Value differs from expected |\n| `matchRegex` | Regular expression match on string value |\n| `exists` | Path exists in rendered output |\n| `notExists` | Path is absent from rendered output |\n| `isEmpty` / `isNotEmpty` | Path is empty or not empty |\n| `isNullOrEmpty` / `isNotNullOrEmpty` | Path is null/empty or present with content |\n| `isKind` | Kubernetes resource kind check |\n| `isAPIVersion` | API version check |\n| `contains` | Array/map contains entry |\n| `notContains` | Array/map does not contain entry |\n| `hasDocuments` | Number of YAML documents rendered |\n| `matchSnapshot` | Snapshot testing |\n| `failedTemplate` | Template should fail to render |\n| `notFailedTemplate` | Template should render successfully |\n| `isSubset` | Rendered output is a superset of expected |\n| `lengthEqual` | Array/map length equals expected count |\n\nUse antonym assertions (`notEqual`, `notContains`, etc.) instead of relying on `not: true` unless that is clearer.\n\nPrefer `equal`, `contains`, and specific negative assertions over broad `exists` checks. Specific assertions catch regressions.\n\n### Assertion Scoping Patterns\n\n```yaml\n  - it: targets a single Deployment by name\n    templates:\n      - templates/deployment.yaml\n      - templates/image-renderer-deployment.yaml\n    asserts:\n      - equal:\n          path: spec.replicas\n          value: 1\n        documentSelector:\n          path: metadata.name\n          value: RELEASE-NAME-grafana\n```\n\n```yaml\n  - it: counts only selected docs\n    template: templates/extra-manifests.yaml\n    documentSelector:\n      path: kind\n      value: ConfigMap\n      matchMany: true\n    asserts:\n      - hasDocuments:\n          count: 2\n          filterAware: true\n```\n\n### Multi-Template Safety\n\nIf a suite includes workload templates plus `config.yaml`, set `template` on every assertion unless the test intentionally targets all templates.\n\nPut `template` at the assertion root, not inside assertion parameters.\n\nWrong:\n\n```yaml\n      - notContains:\n          template: backend/statefulset.yaml\n          path: spec.template.spec.containers\n          content:\n            name: loki-sc-rules\n```\n\nCorrect:\n\n```yaml\n      - template: backend/statefulset.yaml\n        notContains:\n          path: spec.template.spec.containers\n          content:\n            name: loki-sc-rules\n```\n\n### Path and jsonPath Guidance\n\n- Prefer precise paths over broad existence checks.\n- When map keys contain dots or slashes, use jsonPath bracket syntax.\n- Keep escaping consistent to avoid false negatives.\n\n```yaml\n  - equal:\n      path: metadata.annotations[\"kubernetes.io/ingress.class\"]\n      value: nginx\n```\n\n### Conditional Rendering Tests\n\n```yaml\n  - it: should not render when disabled\n    set:\n      component.enabled: false\n    asserts:\n      - hasDocuments:\n          count: 0\n```\n\n### Testing with Release Values\n\n```yaml\n  - it: should use release name in labels\n    release:\n      name: my-release\n      namespace: my-namespace\n    asserts:\n      - equal:\n          path: metadata.namespace\n          value: my-namespace\n```\n\n## Test File Organization\n\nMirror the template directory structure:\n\n```text\ncharts/<chart>/tests/\n  deployment_test.yaml\n  service_test.yaml\n  ingester/\n    statefulset_test.yaml\n  compactor/\n    deployment_test.yaml\n```\n\nTest filenames must end with `.yaml`. This repository configures helm-unittest with `--file 'tests/**/*.yaml'`, so any `.yaml` filename is valid. `<template>_test.yaml` is preferred.\n\n## Writing Workflow\n\n1. Read the template being tested. Understand every conditional, value reference, helper call, and document emitted.\n2. Read `_helpers.tpl` and any other helper partials used by the template.\n3. Read `values.yaml` to understand defaults and the full value schema.\n4. Map render targets: determine whether the template emits zero, one, or many documents and which selector is stable.\n5. Write tests for default rendering, significant conditional branches, selector behavior, multi-template scoping, and edge cases.\n6. Run the tests.\n7. Fix failures by adjusting assertions to match actual rendered output.\n8. Repeat until the test file passes.\n\n## Running Tests\n\nRun all charts:\n\n```bash\nmake helm-unittest\n```\n\nRun tests for one chart:\n\n```bash\nmake helm-unittest HELM_CHART=<chart-name>\n```\n\nRun one test file:\n\n```bash\nmake helm-unittest HELM_CHART=<chart-name> HELM_UNITTEST_FILE='tests/<subdir>/<file>_test.yaml'\n```\n\n## Rules\n\n- Only create or edit `.yaml` files under `charts/*/tests/` when this skill is being used specifically to write tests.\n- Do not modify templates, `values.yaml`, `Chart.yaml`, or non-test files as part of a test-writing task unless the user explicitly expands the scope.\n- Never run destructive shell commands.\n- Use `RELEASE-NAME` as the default release name in assertions.\n- Always set deployment-mode-style flags explicitly. Do not rely on defaults when a chart has conditional rendering modes.\n- When a template has subchart dependencies, use `set` to provide required subchart values.\n- Always run relevant helm-unittest commands after writing tests.\n- If a test run reveals the template does not render with default values, inspect `values.yaml` and adjust the test setup.\n- Prefer `documentSelector` over hardcoded `documentIndex` for templates that can reorder output.\n- Use `hasDocuments.filterAware: true` when asserting counts under selector/index filtering.\n- Use `template` / `templates` at test or assertion level to prevent cross-template assertion bleed.\n- For negative paths, assert absence with `notExists` or `notContains`.\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","rawUrl":"https://raw.githubusercontent.com/prometheus-community/helm-charts/HEAD/AGENTS.md","title":"AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"# Instructions for AI Agents\n\nThe following guidelines apply to all files in this repository.\n\n## Repository Overview\n\nThis is the **Prometheus Community Helm Charts** repository — a collection of Helm charts for Prometheus ecosystem components. Charts are published to both a Helm repository (`prometheus-community`) and as OCI artifacts on `ghcr.io`.\n\n## Charts\n\nAll charts live under `charts/` with a subfolder for each chart.  The subfolder names must match the chart name as described in the Chart.yaml file `.name`.\n\nEach chart follows standard Helm structure (`Chart.yaml`, `values.yaml`, `templates/`). Some charts will organize components into subdirectories (e.g., `templates/grafana/`, `templates/prometheus/`, `templates/alertmanager/` in `kube-prometheus-stack`).\n\n## Feature Implementation Workflow\n\nMost agent tasks in this repository are chart feature changes. For these tasks:\n\n1. Identify the affected chart under `charts/<chart>/` and keep changes scoped to that chart.\n2. Read the relevant `Chart.yaml`, `values.yaml`, templates, helpers, and existing tests before editing.\n3. Implement the feature using the chart's existing template style and values structure.\n4. If `values.yaml` changes in a schema-enabled chart, update schema annotations and regenerate `values.schema.json`.\n5. Add or update focused helm-unittest coverage for the rendered behavior controlled by the feature.\n6. Bump the chart version in `Chart.yaml` according to SemVer.\n7. Run the relevant validation commands, normally `helm unittest --strict --file 'unittests/**/*.yaml' charts/<chart-name>` and any required schema generation command.\n\nAsk the user for clarification only when the intended chart, feature behavior, or compatibility impact cannot be inferred from the request and local context.\n\n## Values Schema\n\nSome charts generate `values.schema.json` from `values.yaml` using `helm-values-schema-json`. A chart uses this flow if `values.yaml` contains `# @schema` comments or a top-level `# $schema: ./values.schema.json` comment. Upstream documentation lives at https://github.com/losisin/helm-values-schema-json/blob/main/docs/README.md; use Context7 for current docs when available.\n\nHelm validates chart values with JSON Schema draft-07. Keep generated schemas compatible with draft-07 even if external schema tooling supports newer drafts.\n\nWhen changing `values.yaml` in a schema-enabled chart:\n\n- Use the `helm-values-schema` skill for detailed schema annotation and regeneration rules.\n- Preserve and update nearby `# @schema` annotations.\n- Add `# @schema` annotations when inferred schema types would be wrong or too loose.\n- Keep `# @schema` comments before helm-docs comments (`# -- ...`) when both are present.\n- Regenerate `values.schema.json` with `helm schema` from the chart directory and include it in the change.\n- Add or update helm-unittest coverage for rendered behavior controlled by the changed values.\n\n## pre-commit testing\n\n### helm-unittests\n\nPull Requests against this repository require that all charts which implement helm-unittests(https://github.com/helm-unittest/helm-unittest) must pass all of their unittests. CI runs them as an `additional-commands` entry of `ct lint` (see `.github/linters/ct.yaml`). The same command run from the repository root:\n\n```bash\nhelm unittest --strict --file 'unittests/**/*.yaml' charts/<chart-name>\n```\n\n### per-chart lint scripts\n\nA chart may carry a `ci/lint.sh`, which `ct lint` runs in addition to the unittests. `kube-prometheus-stack` uses it to verify that the generated CRDs, rules and dashboards are in sync, so changes there have to be produced by the scripts under `hack/` rather than edited in place.\n\n## Contributing Conventions\n\n- **One chart per PR**: CI enforces that PRs only change a single chart.\n- **PR title format**: Must start with `[chart-name] ` (e.g., `[grafana] Add new feature`).\n- **Version bumps**: Every chart change (excluding files listed in `.helmignore`) requires a SemVer version bump in `Chart.yaml`. Major bumps for breaking changes.\n- **DCO sign-off**: Commits must include `Signed-off-by` line (`git commit -s`).\n- **Squash merge only**: The repository only allows squash merges.\n- **Generated files**: `.github/CODEOWNERS`, `MAINTAINERS.md` and `.github/advanced-issue-labeler.yml` are generated from `charts/` by `scripts/generate-codeowners.sh`, `scripts/generate-maintainers.sh` and `scripts/generate-labeler.sh`. Do not edit them directly.\n- **Minimum Kubernetes version**: Charts that declare `kubeVersion` in `Chart.yaml` use a `>=` range, and the value differs per chart (`>=1.25.0-0` for `kube-prometheus-stack`, lower elsewhere). Most charts declare none at all. Match the chart you are editing instead of assuming a repository-wide floor.\n\n## Dependency Management\n\nRenovate manages all dependency updates.\n","isInternal":false,"tokens":1065,"sizeBytes":4830},{"name":"SKILL.md","path":".agents/skills/bump-prometheus-operator/SKILL.md","rawUrl":"https://raw.githubusercontent.com/prometheus-community/helm-charts/HEAD/.agents/skills/bump-prometheus-operator/SKILL.md","title":"bump-prometheus-operator","category":"anthropic-skill","format":"markdown","content":"---\nname: bump-prometheus-operator\ndescription: >-\n  Bump the prometheus-operator version shipped by the kube-prometheus-stack\n  chart. Use when a new prometheus-operator/prometheus-operator release is out\n  and the chart's appVersion needs to follow it: syncs CRDs, checks for new CRD\n  kinds, RBAC changes and newly added spec fields, bumps the chart version,\n  updates UPGRADE.md, and opens a PR. Triggers on \"bump prometheus-operator\",\n  \"update kube-prometheus-stack to the latest operator\", \"sync operator CRDs\".\n---\n\n# Bump prometheus-operator in kube-prometheus-stack\n\nPromotes the `appVersion` of `charts/kube-prometheus-stack` to a new\n`prometheus-operator/prometheus-operator` release and brings everything that\ntravels with the operator (CRDs, RBAC, upgrade notes) along with it.\n\n## Scope of an operator bump\n\nThe operator version is the chart's `appVersion`. A bump touches a small,\nfixed set of files — mirror the most recent merged bump PR (search\n`git log --oneline -S \"appVersion: v\" -- charts/kube-prometheus-stack/Chart.yaml`)\nrather than improvising:\n\n- `charts/kube-prometheus-stack/Chart.yaml` — `appVersion` + chart `version`\n- `charts/kube-prometheus-stack/charts/crds/crds/crd-*.yaml` (10 CRDs) and\n  `charts/crds/files/crds.bz2` — regenerated, never hand-edited\n- `charts/kube-prometheus-stack/UPGRADE.md` — new section\n- `charts/kube-prometheus-stack/templates/prometheus-operator/clusterrole.yaml`\n  — only if the operator's RBAC actually changed (see step 4)\n\n## Procedure\n\n### 1. Find the target version & branch\n\n```bash\n# Latest non-prerelease operator tag\ncurl -s https://api.github.com/repos/prometheus-operator/prometheus-operator/releases/latest | jq -r .tag_name\ngit checkout -b kube-prometheus-stack-bump-operator-<vX.Y.Z> upstream/main\n```\n\nAlways branch off a fresh `upstream/main` so the PR diff is just the bump.\n\n### 2. Bump Chart.yaml\n\nSet `appVersion` to the new `vX.Y.Z`. Bump the chart `version` following the\nprecedent of the previous bump: historically a **minor** operator bump\n(e.g. `v0.91.0 → v0.92.0`) is released as a **major** chart bump\n(e.g. `86.x → 87.0.0`). Confirm the convention against the last bump PR.\n\n### 3. Regenerate CRDs\n\n`hack/update_crds.sh` reads `appVersion` from `Chart.yaml`, so bump Chart.yaml\n**first**, then:\n\n```bash\nbash charts/kube-prometheus-stack/hack/update_crds.sh\n```\n\nThis downloads the 10 CRDs from\n`prometheus-operator/.../<appVersion>/example/prometheus-operator-crd/` and\nrebuilds `charts/crds/files/crds.bz2`.\n\n**Check for new CRD kinds** — if the operator added a CRD, the `FILES` array in\n`update_crds.sh` (and the `crds` subchart) must be extended:\n\n```bash\ndiff \\\n  <(curl -s \"https://api.github.com/repos/prometheus-operator/prometheus-operator/contents/example/prometheus-operator-crd?ref=<OLD>\" | jq -r '.[].name' | sort) \\\n  <(curl -s \"https://api.github.com/repos/prometheus-operator/prometheus-operator/contents/example/prometheus-operator-crd?ref=<NEW>\" | jq -r '.[].name' | sort)\n```\n\n### 4. Check RBAC\n\nThe chart's operator `ClusterRole` is maintained by hand, so confirm whether the\noperator's required RBAC changed between versions:\n\n```bash\nf=example/rbac/prometheus-operator/prometheus-operator-cluster-role.yaml\ndiff \\\n  <(curl -s \"https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/<OLD>/$f\") \\\n  <(curl -s \"https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/<NEW>/$f\")\n```\n\nA diff in only the `app.kubernetes.io/version` label = **no change needed**.\nAny new/removed `rules` entry = update\n`templates/prometheus-operator/clusterrole.yaml` to match. Most patch/minor\noperator bumps need no RBAC change.\n\n### 5. Check for new spec fields\n\nNew CRD properties arrive silently with the regenerated CRDs — the chart renders\neach `*Spec` field explicitly, so a field nobody wires up stays unreachable\nexcept through `additionalConfig`. Diff the regenerated CRDs against the\ncommitted ones to find what the release added:\n\n```bash\ncd charts/kube-prometheus-stack/charts/crds/crds\nfor f in crd-*.yaml; do python3 - \"$f\" <<'PY'\nimport subprocess, sys, yaml\nf = sys.argv[1]\n# crd-alertmanagerconfigs.yaml contains a bare `=`, which SafeLoader rejects\nyaml.SafeLoader.add_constructor(\"tag:yaml.org,2002:value\", lambda l, n: l.construct_scalar(n))\ndef paths(doc, prefix=\"\"):\n    out = set()\n    for k, v in (doc.get(\"properties\") or {}).items():\n        out.add(prefix + k)\n        out |= paths(v, prefix + k + \".\")\n    return out\ndef spec(doc):\n    return doc[\"spec\"][\"versions\"][0][\"schema\"][\"openAPIV3Schema\"][\"properties\"][\"spec\"]\nold = yaml.safe_load(subprocess.run([\"git\", \"show\", f\"HEAD:./{f}\"], capture_output=True, text=True).stdout)\nadded = paths(spec(yaml.safe_load(open(f)))) - paths(spec(old))\nif added:\n    print(f, *sorted(added), sep=\"\\n  \")\nPY\ndone\n```\n\nThen check which of the added paths the chart can already reach: grep the\nrendering template for `.Values.<component>Spec.<field>`. A field passed through\n`toYaml`/`with` covers its whole subtree; one rendered key by key (`tsdb`,\n`thanos`) only covers the sub-keys it names.\n\n**Exposing them is a separate PR.** Keep the bump to the file set above — a\nfollow-up adds the values, the template lines and helm-unittest coverage with a\nminor chart bump. The same sweep run against the full CRD (not just the diff)\nfinds older gaps too; see #7270 and #7272 for both shapes.\n\n### 6. Update UPGRADE.md\n\nPrepend a `## From <old-major>.x to <new-major>.x` section. Copy the previous\nsection's wording and the 10 `kubectl apply --server-side -f .../<NEW>/...`\nCRD commands, swapping the version.\n\n### 7. Validate\n\n```bash\ncd charts/kube-prometheus-stack\nhelm dependency build .        # required, or lint nil-pointers on subchart values\nhelm lint .\nhelm template t . | grep 'prometheus-operator:'   # must show the new vX.Y.Z\n```\n\n> CRDs live in the Helm-native `charts/crds/crds/` directory and are **not**\n> rendered by `helm template` — that is expected. The `crds.bz2` only feeds the\n> optional `crds.upgradeJob`.\n\n### 8. Commit & PR\n\n- Sign off (DCO) — see `CONTRIBUTING.md#sign-off-your-work`.\n- Title: `[kube-prometheus-stack] Bump prometheus-operator to vX.Y.Z`.\n- On review updates, add new commits — **do not squash** (the PR is squashed on\n  merge).\n- Fill the PR template; tick DCO + Chart Version bumped + title-starts-with-chart.\n","frontmatter":{"name":"bump-prometheus-operator","description":"Bump the prometheus-operator version shipped by the kube-prometheus-stack chart. Use when a new prometheus-operator/prometheus-operator release is out and the chart's appVersion needs to follow it: syncs CRDs, checks for new CRD kinds, RBAC changes and newly added spec fields, bumps the chart version, updates UPGRADE.md, and opens a PR. Triggers on \"bump prometheus-operator\", \"update kube-prometheus-stack to the latest operator\", \"sync operator CRDs\"."},"isInternal":false,"tokens":1706,"sizeBytes":6377},{"name":"SKILL.md","path":".agents/skills/helm-chart-test/SKILL.md","rawUrl":"https://raw.githubusercontent.com/prometheus-community/helm-charts/HEAD/.agents/skills/helm-chart-test/SKILL.md","title":"helm-chart-test","category":"anthropic-skill","format":"markdown","content":"---\nname: helm-chart-test\ndescription: Plan, write, and validate helm-unittest tests for a chart. Discovers chart structure, maps coverage gaps, and applies repository helm-unittest conventions.\nuser_invocable: true\n---\n\n# /helm-chart-test [chart] [component]\n\nUse this skill whenever the user asks to add, expand, fix, or review helm-unittest coverage for a chart, or when a chart feature change needs matching rendered-manifest tests.\n\n## Argument Handling\n\n**During feature implementation**, infer the chart and component from the files being changed or from the requested feature. Add or update focused tests for the affected rendered behavior without pausing for broad coverage analysis or scoping questions, unless the requested behavior is ambiguous.\n\n**If no arguments are provided for a standalone test task**, ask the user which chart they want to work on, then proceed as if they provided just the chart name.\n\n**If only `<chart>` is provided for a standalone coverage audit**, run the full discovery and coverage analysis below before asking any questions.\n\n**If `<chart> <component>` is provided for a standalone test task**, inspect that component and choose the relevant existing or new test files. Ask scoping questions only when the requested coverage depth or target templates cannot be inferred.\n\n## Feature Implementation Mode\n\nWhen this skill is used as part of implementing a chart feature, do not stop after planning or ask the user to choose a component. Instead:\n\n1. Identify the affected chart from `charts/<chart>/...`.\n2. Identify affected templates, helpers, and values from the feature diff or requested change.\n3. Read existing nearby tests and mirror their style.\n4. Add or update focused tests for the new or changed rendered behavior.\n5. Cover important enabled/disabled branches, value propagation, selectors, labels, annotations, containers, volumes, and service wiring touched by the feature.\n6. Run the relevant `make helm-unittest HELM_CHART=<chart-name>` command.\n\nAsk the user only when there are multiple plausible feature semantics or when the chart/component cannot be determined from local context.\n\n## Discovery and Coverage Analysis\n\nWork through these steps silently. Produce a single structured report at the end.\n\n### 1. Understand the Chart Structure\n\n- Read `charts/<chart>/Chart.yaml` and note the chart type, version, kubeVersion, and dependencies.\n- Read the top level of `charts/<chart>/values.yaml` to understand major configuration axes, deployment modes, and component enable flags.\n- List `charts/<chart>/templates/**`.\n- Identify component groups. Subdirectories under `templates/` are natural groups. If the chart has flat templates, treat the whole chart as one component.\n- Read `_helpers.tpl` and any other `_*.tpl` files before testing templates that call helpers.\n\n### 2. Map Existing Test Coverage\n\n- List `charts/<chart>/tests/**`.\n- For each component group, count:\n  - renderable templates, excluding `_*.tpl` helper/partial files\n  - corresponding test files in `charts/<chart>/tests/<component>/`\n- Check whether existing tests exercise the relevant branches, not just whether a file exists.\n\n### 3. Assess Complexity\n\nDetermine whether the chart is **simple** or **complex**.\n\n- **Simple**: flat templates, no deployment modes, fewer than 10 renderable templates.\n- **Complex**: subdirectories, deployment modes, major conditional rendering, or more than 10 renderable templates.\n\nFor a simple chart, present a single coverage table and recommend whether to proceed with the whole chart at once.\n\nFor a complex chart, group templates into logical work units and recommend a starting component.\n\n### 4. Present the Coverage Report\n\nUse this format:\n\n```md\n## <chart> - Test Coverage Analysis\n\n| Component | Renderable templates | Test files | Coverage |\n|---|---:|---:|---|\n| core / root-level | N | N | None / Partial / Good |\n| gateway | N | N | None / Partial / Good |\n| ingester | N | N | None / Partial / Good |\n\n### Notes\n- <important observations about deployment modes, required values, lookup usage, or test complexity>\n\n### Suggested starting point\n<recommend the lowest-risk, highest-value component and explain why>\n\nRecommended next test target: <component or whole chart>\n```\n\nFor standalone coverage audits, wait for the user to choose a component before writing tests. For feature implementation, proceed with focused tests for the component touched by the feature.\n\n## Scoping Questions\n\nFor standalone test-expansion tasks where scope cannot be inferred, ask:\n\n1. Scope within the component: all templates, or specific templates?\n2. Existing tests: extend partial tests, or add new test files alongside them?\n3. Coverage depth: happy path only, or full branch coverage for every significant `if` / `with` / `range`?\n4. Known gotchas: deployment modes, required values, lookup behavior, subchart values, or compatibility constraints?\n\nAfter the user answers, summarize the agreed scope in one short paragraph, then begin writing tests. Skip these questions when implementing a specific feature and the affected behavior is clear from the request or diff.\n\n## helm-unittest Overview\n\nTests are YAML files in `charts/<chart-name>/tests/` that validate rendered Kubernetes manifests. Each test renders templates with specified values and asserts on the output.\n\nEach `tests[].it` case renders independently with that case's value inputs. Keep tests focused and deterministic: one behavior per test, explicit value overrides, and scoped assertions.\n\n### Test File Structure\n\n```yaml\n# $schema: https://raw.githubusercontent.com/helm-unittest/helm-unittest/refs/heads/main/schema/helm-testsuite.json\nsuite: <descriptive suite name>\nvalues:\n  - ../ci/<values-file>.yaml\nset:\n  key.nested: value\ntemplates:\n  - templates/<path-to-template>.yaml\ntests:\n  - it: <test case description>\n    values:\n      - ./values/<scenario>.yaml\n    set:\n      key.nested: value\n    documentSelector:\n      path: metadata.name\n      value: RELEASE-NAME-myapp\n    asserts:\n      - isKind:\n          of: Deployment\n      - equal:\n          path: metadata.name\n          value: RELEASE-NAME-myapp\n      - contains:\n          path: spec.template.spec.containers[0].env\n          content:\n            name: MY_VAR\n            value: my-value\n```\n\n### Scope, Precedence, and Targeting\n\n- Value precedence: chart `values.yaml` < suite `values` < suite `set` < test `values` < test `set`.\n- Template scope precedence: suite `templates` can be narrowed by test `template` / `templates`, then by assertion-level `template`.\n- Document targeting precedence: assertion `documentSelector` / `documentIndex` overrides test-level selector/index.\n- Use `documentSelector` for multi-document templates instead of brittle numeric `documentIndex` when possible.\n- `hasDocuments` ignores selectors by default; set `filterAware: true` to count only selector/index-filtered documents.\n\n### Suite and Test Options\n\n- `release`: exercise behavior that depends on `.Release` (`name`, `namespace`, `revision`, `upgrade`).\n- `capabilities`: pin Kubernetes versions/APIs for branches guarded by `.Capabilities.*`.\n- `chart`: override `.Chart.version` / `.Chart.appVersion` when template output depends on them.\n- `excludeTemplates`: narrow broad template globs to avoid unrelated documents in a suite.\n- `skip`: only for temporary or unreleased behavior; prefer active assertions over skipped tests.\n- `postRenderer`: use only when chart behavior explicitly depends on post-render transforms.\n\n## Testing `lookup` with `kubernetesProvider`\n\nUse `kubernetesProvider` whenever templates call `lookup`; without it, `lookup` returns empty and branch coverage is incomplete.\n\n- Register API kinds in `scheme` using `\"<group>/<version>/<Kind>\"` or `\"v1/<Kind>\"` for core APIs.\n- Each scheme entry must define `gvr` (`group` optional for core APIs, plus `version`, `resource`) and `namespaced`.\n- Provide fixture resources in `objects`.\n- Test-level `kubernetesProvider.objects` can add scenario-specific fixtures without rewriting suite-wide defaults.\n\n```yaml\ntemplates:\n  - templates/lookup.yaml\nkubernetesProvider:\n  scheme:\n    \"v1/Namespace\":\n      gvr:\n        version: \"v1\"\n        resource: \"namespaces\"\n      namespaced: false\n    \"v1/Pod\":\n      gvr:\n        version: \"v1\"\n        resource: \"pods\"\n      namespaced: true\n    \"networking.k8s.io/v1/Ingress\":\n      gvr:\n        group: \"networking.k8s.io\"\n        version: \"v1\"\n        resource: \"ingresses\"\n      namespaced: true\n  objects:\n    - kind: Pod\n      apiVersion: v1\n      metadata:\n        name: exists\n        namespace: default\ntests:\n  - it: should find existing pod through lookup\n    asserts:\n      - isNotNullOrEmpty:\n          path: pod_exists\n      - equal:\n          path: pod_exists.metadata.name\n          value: exists\n  - it: should find test-level object through lookup\n    kubernetesProvider:\n      objects:\n        - kind: Pod\n          apiVersion: v1\n          metadata:\n            name: not-exists\n            namespace: default\n    asserts:\n      - isNotNullOrEmpty:\n          path: pod_not_exists\n      - equal:\n          path: pod_not_exists.metadata.name\n          value: not-exists\n```\n\n## Assertion Guidance\n\n| Assertion | Purpose |\n|---|---|\n| `equal` | Exact match at JSON path |\n| `notEqual` | Value differs from expected |\n| `matchRegex` | Regular expression match on string value |\n| `exists` | Path exists in rendered output |\n| `notExists` | Path is absent from rendered output |\n| `isEmpty` / `isNotEmpty` | Path is empty or not empty |\n| `isNullOrEmpty` / `isNotNullOrEmpty` | Path is null/empty or present with content |\n| `isKind` | Kubernetes resource kind check |\n| `isAPIVersion` | API version check |\n| `contains` | Array/map contains entry |\n| `notContains` | Array/map does not contain entry |\n| `hasDocuments` | Number of YAML documents rendered |\n| `matchSnapshot` | Snapshot testing |\n| `failedTemplate` | Template should fail to render |\n| `notFailedTemplate` | Template should render successfully |\n| `isSubset` | Rendered output is a superset of expected |\n| `lengthEqual` | Array/map length equals expected count |\n\nUse antonym assertions (`notEqual`, `notContains`, etc.) instead of relying on `not: true` unless that is clearer.\n\nPrefer `equal`, `contains`, and specific negative assertions over broad `exists` checks. Specific assertions catch regressions.\n\n### Assertion Scoping Patterns\n\n```yaml\n  - it: targets a single Deployment by name\n    templates:\n      - templates/deployment.yaml\n      - templates/image-renderer-deployment.yaml\n    asserts:\n      - equal:\n          path: spec.replicas\n          value: 1\n        documentSelector:\n          path: metadata.name\n          value: RELEASE-NAME-grafana\n```\n\n```yaml\n  - it: counts only selected docs\n    template: templates/extra-manifests.yaml\n    documentSelector:\n      path: kind\n      value: ConfigMap\n      matchMany: true\n    asserts:\n      - hasDocuments:\n          count: 2\n          filterAware: true\n```\n\n### Multi-Template Safety\n\nIf a suite includes workload templates plus `config.yaml`, set `template` on every assertion unless the test intentionally targets all templates.\n\nPut `template` at the assertion root, not inside assertion parameters.\n\nWrong:\n\n```yaml\n      - notContains:\n          template: backend/statefulset.yaml\n          path: spec.template.spec.containers\n          content:\n            name: loki-sc-rules\n```\n\nCorrect:\n\n```yaml\n      - template: backend/statefulset.yaml\n        notContains:\n          path: spec.template.spec.containers\n          content:\n            name: loki-sc-rules\n```\n\n### Path and jsonPath Guidance\n\n- Prefer precise paths over broad existence checks.\n- When map keys contain dots or slashes, use jsonPath bracket syntax.\n- Keep escaping consistent to avoid false negatives.\n\n```yaml\n  - equal:\n      path: metadata.annotations[\"kubernetes.io/ingress.class\"]\n      value: nginx\n```\n\n### Conditional Rendering Tests\n\n```yaml\n  - it: should not render when disabled\n    set:\n      component.enabled: false\n    asserts:\n      - hasDocuments:\n          count: 0\n```\n\n### Testing with Release Values\n\n```yaml\n  - it: should use release name in labels\n    release:\n      name: my-release\n      namespace: my-namespace\n    asserts:\n      - equal:\n          path: metadata.namespace\n          value: my-namespace\n```\n\n## Test File Organization\n\nMirror the template directory structure:\n\n```text\ncharts/<chart>/tests/\n  deployment_test.yaml\n  service_test.yaml\n  ingester/\n    statefulset_test.yaml\n  compactor/\n    deployment_test.yaml\n```\n\nTest filenames must end with `.yaml`. This repository configures helm-unittest with `--file 'tests/**/*.yaml'`, so any `.yaml` filename is valid. `<template>_test.yaml` is preferred.\n\n## Writing Workflow\n\n1. Read the template being tested. Understand every conditional, value reference, helper call, and document emitted.\n2. Read `_helpers.tpl` and any other helper partials used by the template.\n3. Read `values.yaml` to understand defaults and the full value schema.\n4. Map render targets: determine whether the template emits zero, one, or many documents and which selector is stable.\n5. Write tests for default rendering, significant conditional branches, selector behavior, multi-template scoping, and edge cases.\n6. Run the tests.\n7. Fix failures by adjusting assertions to match actual rendered output.\n8. Repeat until the test file passes.\n\n## Running Tests\n\nRun all charts:\n\n```bash\nmake helm-unittest\n```\n\nRun tests for one chart:\n\n```bash\nmake helm-unittest HELM_CHART=<chart-name>\n```\n\nRun one test file:\n\n```bash\nmake helm-unittest HELM_CHART=<chart-name> HELM_UNITTEST_FILE='tests/<subdir>/<file>_test.yaml'\n```\n\n## Rules\n\n- Only create or edit `.yaml` files under `charts/*/tests/` when this skill is being used specifically to write tests.\n- Do not modify templates, `values.yaml`, `Chart.yaml`, or non-test files as part of a test-writing task unless the user explicitly expands the scope.\n- Never run destructive shell commands.\n- Use `RELEASE-NAME` as the default release name in assertions.\n- Always set deployment-mode-style flags explicitly. Do not rely on defaults when a chart has conditional rendering modes.\n- When a template has subchart dependencies, use `set` to provide required subchart values.\n- Always run relevant helm-unittest commands after writing tests.\n- If a test run reveals the template does not render with default values, inspect `values.yaml` and adjust the test setup.\n- Prefer `documentSelector` over hardcoded `documentIndex` for templates that can reorder output.\n- Use `hasDocuments.filterAware: true` when asserting counts under selector/index filtering.\n- Use `template` / `templates` at test or assertion level to prevent cross-template assertion bleed.\n- For negative paths, assert absence with `notExists` or `notContains`.\n","frontmatter":{"name":"helm-chart-test","description":"Plan, write, and validate helm-unittest tests for a chart. Discovers chart structure, maps coverage gaps, and applies repository helm-unittest conventions.","user_invocable":true},"isInternal":false,"tokens":3290,"sizeBytes":14886},{"name":"SKILL.md","path":".agents/skills/helm-values-schema/SKILL.md","rawUrl":"https://raw.githubusercontent.com/prometheus-community/helm-charts/HEAD/.agents/skills/helm-values-schema/SKILL.md","title":"helm-values-schema","category":"anthropic-skill","format":"markdown","content":"---\nname: helm-values-schema\ndescription: Maintain values.schema.json for Helm charts that use helm-values-schema-json annotations in values.yaml.\nuser_invocable: true\n---\n\n# /helm-values-schema [chart]\n\nUse this skill when the user asks to add, change, review, or regenerate a Helm chart `values.schema.json`, or when a chart feature changes `values.yaml` in a chart that uses schema annotations.\n\n## Detection\n\nA chart uses `helm-values-schema-json` if `charts/<chart>/values.yaml` contains either:\n\n- `# @schema` comments\n- a top-level schema reference such as `# $schema: ./values.schema.json`\n\nWhen a chart uses this flow, changes to `values.yaml` must keep schema annotations and `values.schema.json` in sync.\n\n## Documentation\n\nPrefer Context7 for current `helm-values-schema-json` docs when available.\n\nUpstream documentation:\n\n```text\nhttps://github.com/losisin/helm-values-schema-json/blob/main/docs/README.md\n```\n\n## Compatibility\n\nHelm validates chart values with JSON Schema draft-07. Keep generated schemas compatible with draft-07 even if external schema tooling supports newer drafts.\n\n## Workflow\n\n1. Read `charts/<chart>/values.yaml`.\n2. Check whether `# @schema` annotations or `# $schema: ./values.schema.json` are present.\n3. If changing or adding values, preserve nearby annotations and add annotations when inferred schema would be wrong or too loose.\n4. Preserve helm-docs comments. When a field has both `# @schema` and helm-docs `# --` comments, `# @schema` comments must be above the helm-docs description comments.\n5. Regenerate `values.schema.json`.\n6. Review the schema diff for only intentional changes.\n7. Ensure values changes also have helm-unittest coverage for rendered behavior where applicable.\n\n## helm-docs Integration\n\n`helm-values-schema-json` supports using descriptions from `helm-docs` comments since v2.0.0, but only when enabled with `--use-helm-docs`.\n\nExample:\n\n```bash\nhelm schema --use-helm-docs\n```\n\n```yaml\n# -- My description\nfullnameOverride: bar\n```\n\nGenerates:\n\n```json\n{\n  \"fullnameOverride\": {\n    \"description\": \"My description\",\n    \"type\": \"string\"\n  }\n}\n```\n\n### Unsupported helm-docs Features\n\nThe schema plugin does not support helm-docs-specific properties such as:\n\n- `# @default --`\n- `# @section --`\n\nIt also does not support detached helm-docs comments. Comments must be directly above the property or inline in a supported form.\n\nSupported:\n\n```yaml\n# fullnameOverride -- This works\nfullnameOverride: bar\n```\n\nNot supported by the schema plugin:\n\n```yaml\nfullnameOverride: bar\n\n# fullnameOverride -- This does not work for schema generation.\nfullnameOverride: bar\n```\n\nHelm-docs itself does not understand `# @schema` comments. When both `# @schema` and helm-docs comments are above a field, put `# @schema` first so schema annotations are not included in the generated description. Treat the inverse order as invalid: helm-docs will include the schema annotation text in the description.\n\nGood:\n\n```yaml\n# @schema maxLength:10\n# -- My awesome nameOverride description\nnameOverride: \"myapp\"\n```\n\nBad:\n\n```yaml\n# -- My awesome nameOverride description\n# @schema maxLength:10\nnameOverride: \"myapp\"\n```\n\n## Annotation Placement\n\n`# @schema` annotations may be placed inline, on the line above a field, or in specific cases below a block. Preserve the surrounding style already used in the chart, except when the existing style conflicts with helm-docs ordering. If a value has a helm-docs `# --` description, any standalone `# @schema` comments for that value must be above the `# --` comment, never between the helm-docs comment and the value.\n\nExamples:\n\n```yaml\nfullnameOverride: \"myapp\" # @schema maxLength:10;pattern:^[a-z]+$\n\n# @schema maxLength:10;pattern:^[a-z]+$\nnameOverride: \"myapp\"\n\n# @schema maxLength:10\n# -- My awesome nameOverride description\nnameOverride: \"myapp\"\n\n# Invalid with helm-docs: the schema annotation becomes part of the description.\n# -- My awesome nameOverride description\n# @schema maxLength:10\nnameOverride: \"myapp\"\n\nresources:\n  limits: {}\n  requests: {}\n# @schema additionalProperties:false\n```\n\nMultiple schema annotations can be separated with semicolons.\n\n## Commands\n\nFor Loki, use the repository target:\n\n```bash\nmake helm-schema HELM_CHART=loki\n```\n\nThe underlying command currently runs:\n\n```bash\nhelm schema --config .github/linters/.schema.yaml -f charts/loki/values.yaml -o charts/loki/values.schema.json\n```\n\nIf adding schema generation for another chart, follow the chart's local Makefile or CI pattern instead of inventing a one-off command.\n\n## Rules\n\n- Do not hand-edit `values.schema.json` when it can be regenerated.\n- Do not remove existing `# @schema` annotations unless the associated value is removed.\n- Keep schema annotations as close as possible to the value they describe.\n- Keep `# @schema` comments above helm-docs `# --` comments. Never add a standalone `# @schema` comment below a helm-docs description comment for the same value.\n- Include regenerated `values.schema.json` in the change.\n- Values changes that affect rendered manifests should also be covered by helm-unittest tests.\n","frontmatter":{"name":"helm-values-schema","description":"Maintain values.schema.json for Helm charts that use helm-values-schema-json annotations in values.yaml.","user_invocable":true},"isInternal":false,"tokens":1181,"sizeBytes":5116},{"name":"copilot-instructions.md","path":".github/copilot-instructions.md","rawUrl":"https://raw.githubusercontent.com/prometheus-community/helm-charts/HEAD/.github/copilot-instructions.md","title":"GitHub Copilot Instructions","category":"copilot-instructions","format":"markdown","content":"# GitHub Copilot Instructions\n\nFollow the repository-wide agent guidance in `AGENTS.md`. This repository contains Helm charts for Prometheus ecosystem components.\n\nMost tasks are Helm chart feature changes. When changing a chart:\n\n- Work within a single chart under `charts/<chart>/`.\n- Read `Chart.yaml`, `values.yaml`, relevant templates, helpers, and existing tests before editing.\n- Follow existing chart patterns before adding new structure.\n- Update `values.yaml`, templates, tests, and generated schema artifacts together when a new value changes rendered behavior.\n- If `values.yaml` contains `# @schema` comments or `# $schema: ./values.schema.json`, follow the `helm-values-schema` skill guidance and regenerate `values.schema.json`.\n- Add or update helm-unittest coverage for rendered behavior changed by templates or values.\n- Run `helm unittest --strict --file 'unittests/**/*.yaml' charts/<chart-name>` for charts with helm-unittest coverage.\n- Bump the chart version in `Chart.yaml` for chart changes not ignored by `.helmignore`.\n- Do not edit generated ownership files such as `.github/CODEOWNERS` or `MAINTAINERS.md` directly.\n","isInternal":false,"tokens":240,"sizeBytes":1145}],"systemPromptSnippet":"<yakaai_skills repo=\"prometheus-community/helm-charts\">\n<!-- File: AGENTS.md (Tokens: ~1065 | Category: root-instruction) -->\n# Instructions for AI Agents\n\nThe following guidelines apply to all files in this repository.\n\n## Repository Overview\n\nThis is the **Prometheus Community Helm Charts** repository — a collection of Helm charts for Prometheus ecosystem components. Charts are published to both a Helm repository (`prometheus-community`) and as OCI artifacts on `ghcr.io`.\n\n## Charts\n\nAll charts live under `charts/` with a subfolder for each chart.  The subfolder names must match the chart name as described in the Chart.yaml file `.name`.\n\nEach chart follows standard Helm structure (`Chart.yaml`, `values.yaml`, `templates/`). Some charts will organize components into subdirectories (e.g., `templates/grafana/`, `templates/prometheus/`, `templates/alertmanager/` in `kube-prometheus-stack`).\n\n## Feature Implementation Workflow\n\nMost agent tasks in this repository are chart feature changes. For these tasks:\n\n1. Identify the affected chart under `charts/<chart>/` and keep changes scoped to that chart.\n2. Read the relevant `Chart.yaml`, `values.yaml`, templates, helpers, and existing tests before editing.\n3. Implement the feature using the chart's existing template style and values structure.\n4. If `values.yaml` changes in a schema-enabled chart, update schema annotations and regenerate `values.schema.json`.\n5. Add or update focused helm-unittest coverage for the rendered behavior controlled by the feature.\n6. Bump the chart version in `Chart.yaml` according to SemVer.\n7. Run the relevant validation commands, normally `helm unittest --strict --file 'unittests/**/*.yaml' charts/<chart-name>` and any required schema generation command.\n\nAsk the user for clarification only when the intended chart, feature behavior, or compatibility impact cannot be inferred from the request and local context.\n\n## Values Schema\n\nSome charts generate `values.schema.json` from `values.yaml` using `helm-values-schema-json`. A chart uses this flow if `values.yaml` contains `# @schema` comments or a top-level `# $schema: ./values.schema.json` comment. Upstream documentation lives at https://github.com/losisin/helm-values-schema-json/blob/main/docs/README.md; use Context7 for current docs when available.\n\nHelm validates chart values with JSON Schema draft-07. Keep generated schemas compatible with draft-07 even if external schema tooling supports newer drafts.\n\nWhen changing `values.yaml` in a schema-enabled chart:\n\n- Use the `helm-values-schema` skill for detailed schema annotation and regeneration rules.\n- Preserve and update nearby `# @schema` annotations.\n- Add `# @schema` annotations when inferred schema types would be wrong or too loose.\n- Keep `# @schema` comments before helm-docs comments (`# -- ...`) when both are present.\n- Regenerate `values.schema.json` with `helm schema` from the chart directory and include it in the change.\n- Add or update helm-unittest coverage for rendered behavior controlled by the changed values.\n\n## pre-commit testing\n\n### helm-unittests\n\nPull Requests against this repository require that all charts which implement helm-unittests(https://github.com/helm-unittest/helm-unittest) must pass all of their unittests. CI runs them as an `additional-commands` entry of `ct lint` (see `.github/linters/ct.yaml`). The same command run from the repository root:\n\n```bash\nhelm unittest --strict --file 'unittests/**/*.yaml' charts/<chart-name>\n```\n\n### per-chart lint scripts\n\nA chart may carry a `ci/lint.sh`, which `ct lint` runs in addition to the unittests. `kube-prometheus-stack` uses it to verify that the generated CRDs, rules and dashboards are in sync, so changes there have to be produced by the scripts under `hack/` rather than edited in place.\n\n## Contributing Conventions\n\n- **One chart per PR**: CI enforces that PRs only change a single chart.\n- **PR title format**: Must start with `[chart-name] ` (e.g., `[grafana] Add new feature`).\n- **Version bumps**: Every chart change (excluding files listed in `.helmignore`) requires a SemVer version bump in `Chart.yaml`. Major bumps for breaking changes.\n- **DCO sign-off**: Commits must include `Signed-off-by` line (`git commit -s`).\n- **Squash merge only**: The repository only allows squash merges.\n- **Generated files**: `.github/CODEOWNERS`, `MAINTAINERS.md` and `.github/advanced-issue-labeler.yml` are generated from `charts/` by `scripts/generate-codeowners.sh`, `scripts/generate-maintainers.sh` and `scripts/generate-labeler.sh`. Do not edit them directly.\n- **Minimum Kubernetes version**: Charts that declare `kubeVersion` in `Chart.yaml` use a `>=` range, and the value differs per chart (`>=1.25.0-0` for `kube-prometheus-stack`, lower elsewhere). Most charts declare none at all. Match the chart you are editing instead of assuming a repository-wide floor.\n\n## Dependency Management\n\nRenovate manages all dependency updates.\n\n<!-- File: .agents/skills/bump-prometheus-operator/SKILL.md (Tokens: ~1706 | Category: anthropic-skill) -->\n---\nname: bump-prometheus-operator\ndescription: >-\n  Bump the prometheus-operator version shipped by the kube-prometheus-stack\n  chart. Use when a new prometheus-operator/prometheus-operator release is out\n  and the chart's appVersion needs to follow it: syncs CRDs, checks for new CRD\n  kinds, RBAC changes and newly added spec fields, bumps the chart version,\n  updates UPGRADE.md, and opens a PR. Triggers on \"bump prometheus-operator\",\n  \"update kube-prometheus-stack to the latest operator\", \"sync operator CRDs\".\n---\n\n# Bump prometheus-operator in kube-prometheus-stack\n\nPromotes the `appVersion` of `charts/kube-prometheus-stack` to a new\n`prometheus-operator/prometheus-operator` release and brings everything that\ntravels with the operator (CRDs, RBAC, upgrade notes) along with it.\n\n## Scope of an operator bump\n\nThe operator version is the chart's `appVersion`. A bump touches a small,\nfixed set of files — mirror the most recent merged bump PR (search\n`git log --oneline -S \"appVersion: v\" -- charts/kube-prometheus-stack/Chart.yaml`)\nrather than improvising:\n\n- `charts/kube-prometheus-stack/Chart.yaml` — `appVersion` + chart `version`\n- `charts/kube-prometheus-stack/charts/crds/crds/crd-*.yaml` (10 CRDs) and\n  `charts/crds/files/crds.bz2` — regenerated, never hand-edited\n- `charts/kube-prometheus-stack/UPGRADE.md` — new section\n- `charts/kube-prometheus-stack/templates/prometheus-operator/clusterrole.yaml`\n  — only if the operator's RBAC actually changed (see step 4)\n\n## Procedure\n\n### 1. Find the target version & branch\n\n```bash\n# Latest non-prerelease operator tag\ncurl -s https://api.github.com/repos/prometheus-operator/prometheus-operator/releases/latest | jq -r .tag_name\ngit checkout -b kube-prometheus-stack-bump-operator-<vX.Y.Z> upstream/main\n```\n\nAlways branch off a fresh `upstream/main` so the PR diff is just the bump.\n\n### 2. Bump Chart.yaml\n\nSet `appVersion` to the new `vX.Y.Z`. Bump the chart `version` following the\nprecedent of the previous bump: historically a **minor** operator bump\n(e.g. `v0.91.0 → v0.92.0`) is released as a **major** chart bump\n(e.g. `86.x → 87.0.0`). Confirm the convention against the last bump PR.\n\n### 3. Regenerate CRDs\n\n`hack/update_crds.sh` reads `appVersion` from `Chart.yaml`, so bump Chart.yaml\n**first**, then:\n\n```bash\nbash charts/kube-prometheus-stack/hack/update_crds.sh\n```\n\nThis downloads the 10 CRDs from\n`prometheus-operator/.../<appVersion>/example/prometheus-operator-crd/` and\nrebuilds `charts/crds/files/crds.bz2`.\n\n**Check for new CRD kinds** — if the operator added a CRD, the `FILES` array in\n`update_crds.sh` (and the `crds` subchart) must be extended:\n\n```bash\ndiff \\\n  <(curl -s \"https://api.github.com/repos/prometheus-operator/prometheus-operator/contents/example/prometheus-operator-crd?ref=<OLD>\" | jq -r '.[].name' | sort) \\\n  <(curl -s \"https://api.github.com/repos/prometheus-operator/prometheus-operator/contents/example/prometheus-operator-crd?ref=<NEW>\" | jq -r '.[].name' | sort)\n```\n\n### 4. Check RBAC\n\nThe chart's operator `ClusterRole` is maintained by hand, so confirm whether the\noperator's required RBAC changed between versions:\n\n```bash\nf=example/rbac/prometheus-operator/prometheus-operator-cluster-role.yaml\ndiff \\\n  <(curl -s \"https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/<OLD>/$f\") \\\n  <(curl -s \"https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/<NEW>/$f\")\n```\n\nA diff in only the `app.kubernetes.io/version` label = **no change needed**.\nAny new/removed `rules` entry = update\n`templates/prometheus-operator/clusterrole.yaml` to match. Most patch/minor\noperator bumps need no RBAC change.\n\n### 5. Check for new spec fields\n\nNew CRD properties arrive silently with the regenerated CRDs — the chart renders\neach `*Spec` field explicitly, so a field nobody wires up stays unreachable\nexcept through `additionalConfig`. Diff the regenerated CRDs against the\ncommitted ones to find what the release added:\n\n```bash\ncd charts/kube-prometheus-stack/charts/crds/crds\nfor f in crd-*.yaml; do python3 - \"$f\" <<'PY'\nimport subprocess, sys, yaml\nf = sys.argv[1]\n# crd-alertmanagerconfigs.yaml contains a bare `=`, which SafeLoader rejects\nyaml.SafeLoader.add_constructor(\"tag:yaml.org,2002:value\", lambda l, n: l.construct_scalar(n))\ndef paths(doc, prefix=\"\"):\n    out = set()\n    for k, v in (doc.get(\"properties\") or {}).items():\n        out.add(prefix + k)\n        out |= paths(v, prefix + k + \".\")\n    return out\ndef spec(doc):\n    return doc[\"spec\"][\"versions\"][0][\"schema\"][\"openAPIV3Schema\"][\"properties\"][\"spec\"]\nold = yaml.safe_load(subprocess.run([\"git\", \"show\", f\"HEAD:./{f}\"], capture_output=True, text=True).stdout)\nadded = paths(spec(yaml.safe_load(open(f)))) - paths(spec(old))\nif added:\n    print(f, *sorted(added), sep=\"\\n  \")\nPY\ndone\n```\n\nThen check which of the added paths the chart can already reach: grep the\nrendering template for `.Values.<component>Spec.<field>`. A field passed through\n`toYaml`/`with` covers its whole subtree; one rendered key by key (`tsdb`,\n`thanos`) only covers the sub-keys it names.\n\n**Exposing them is a separate PR.** Keep the bump to the file set above — a\nfollow-up adds the values, the template lines and helm-unittest coverage with a\nminor chart bump. The same sweep run against the full CRD (not just the diff)\nfinds older gaps too; see #7270 and #7272 for both shapes.\n\n### 6. Update UPGRADE.md\n\nPrepend a `## From <old-major>.x to <new-major>.x` section. Copy the previous\nsection's wording and the 10 `kubectl apply --server-side -f .../<NEW>/...`\nCRD commands, swapping the version.\n\n### 7. Validate\n\n```bash\ncd charts/kube-prometheus-stack\nhelm dependency build .        # required, or lint nil-pointers on subchart values\nhelm lint .\nhelm template t . | grep 'prometheus-operator:'   # must show the new vX.Y.Z\n```\n\n> CRDs live in the Helm-native `charts/crds/crds/` directory and are **not**\n> rendered by `helm template` — that is expected. The `crds.bz2` only feeds the\n> optional `crds.upgradeJob`.\n\n### 8. Commit & PR\n\n- Sign off (DCO) — see `CONTRIBUTING.md#sign-off-your-work`.\n- Title: `[kube-prometheus-stack] Bump prometheus-operator to vX.Y.Z`.\n- On review updates, add new commits — **do not squash** (the PR is squashed on\n  merge).\n- Fill the PR template; tick DCO + Chart Version bumped + title-starts-with-chart.\n\n<!-- File: .agents/skills/helm-chart-test/SKILL.md (Tokens: ~3290 | Category: anthropic-skill) -->\n---\nname: helm-chart-test\ndescription: Plan, write, and validate helm-unittest tests for a chart. Discovers chart structure, maps coverage gaps, and applies repository helm-unittest conventions.\nuser_invocable: true\n---\n\n# /helm-chart-test [chart] [component]\n\nUse this skill whenever the user asks to add, expand, fix, or review helm-unittest coverage for a chart, or when a chart feature change needs matching rendered-manifest tests.\n\n## Argument Handling\n\n**During feature implementation**, infer the chart and component from the files being changed or from the requested feature. Add or update focused tests for the affected rendered behavior without pausing for broad coverage analysis or scoping questions, unless the requested behavior is ambiguous.\n\n**If no arguments are provided for a standalone test task**, ask the user which chart they want to work on, then proceed as if they provided just the chart name.\n\n**If only `<chart>` is provided for a standalone coverage audit**, run the full discovery and coverage analysis below before asking any questions.\n\n**If `<chart> <component>` is provided for a standalone test task**, inspect that component and choose the relevant existing or new test files. Ask scoping questions only when the requested coverage depth or target templates cannot be inferred.\n\n## Feature Implementation Mode\n\nWhen this skill is used as part of implementing a chart feature, do not stop after planning or ask the user to choose a component. Instead:\n\n1. Identify the affected chart from `charts/<chart>/...`.\n2. Identify affected templates, helpers, and values from the feature diff or requested change.\n3. Read existing nearby tests and mirror their style.\n4. Add or update focused tests for the new or changed rendered behavior.\n5. Cover important enabled/disabled branches, value propagation, selectors, labels, annotations, containers, volumes, and service wiring touched by the feature.\n6. Run the relevant `make helm-unittest HELM_CHART=<chart-name>` command.\n\nAsk the user only when there are multiple plausible feature semantics or when the chart/component cannot be determined from local context.\n\n## Discovery and Coverage Analysis\n\nWork through these steps silently. Produce a single structured report at the end.\n\n### 1. Understand the Chart Structure\n\n- Read `charts/<chart>/Chart.yaml` and note the chart type, version, kubeVersion, and dependencies.\n- Read the top level of `charts/<chart>/values.yaml` to understand major configuration axes, deployment modes, and component enable flags.\n- List `charts/<chart>/templates/**`.\n- Identify component groups. Subdirectories under `templates/` are natural groups. If the chart has flat templates, treat the whole chart as one component.\n- Read `_helpers.tpl` and any other `_*.tpl` files before testing templates that call helpers.\n\n### 2. Map Existing Test Coverage\n\n- List `charts/<chart>/tests/**`.\n- For each component group, count:\n  - renderable templates, excluding `_*.tpl` helper/partial files\n  - corresponding test files in `charts/<chart>/tests/<component>/`\n- Check whether existing tests exercise the relevant branches, not just whether a file exists.\n\n### 3. Assess Complexity\n\nDetermine whether the chart is **simple** or **complex**.\n\n- **Simple**: flat templates, no deployment modes, fewer than 10 renderable templates.\n- **Complex**: subdirectories, deployment modes, major conditional rendering, or more than 10 renderable templates.\n\nFor a simple chart, present a single coverage table and recommend whether to proceed with the whole chart at once.\n\nFor a complex chart, group templates into logical work units and recommend a starting component.\n\n### 4. Present the Coverage Report\n\nUse this format:\n\n```md\n## <chart> - Test Coverage Analysis\n\n| Component | Renderable templates | Test files | Coverage |\n|---|---:|---:|---|\n| core / root-level | N | N | None / Partial / Good |\n| gateway | N | N | None / Partial / Good |\n| ingester | N | N | None / Partial / Good |\n\n### Notes\n- <important observations about deployment modes, required values, lookup usage, or test complexity>\n\n### Suggested starting point\n<recommend the lowest-risk, highest-value component and explain why>\n\nRecommended next test target: <component or whole chart>\n```\n\nFor standalone coverage audits, wait for the user to choose a component before writing tests. For feature implementation, proceed with focused tests for the component touched by the feature.\n\n## Scoping Questions\n\nFor standalone test-expansion tasks where scope cannot be inferred, ask:\n\n1. Scope within the component: all templates, or specific templates?\n2. Existing tests: extend partial tests, or add new test files alongside them?\n3. Coverage depth: happy path only, or full branch coverage for every significant `if` / `with` / `range`?\n4. Known gotchas: deployment modes, required values, lookup behavior, subchart values, or compatibility constraints?\n\nAfter the user answers, summarize the agreed scope in one short paragraph, then begin writing tests. Skip these questions when implementing a specific feature and the affected behavior is clear from the request or diff.\n\n## helm-unittest Overview\n\nTests are YAML files in `charts/<chart-name>/tests/` that validate rendered Kubernetes manifests. Each test renders templates with specified values and asserts on the output.\n\nEach `tests[].it` case renders independently with that case's value inputs. Keep tests focused and deterministic: one behavior per test, explicit value overrides, and scoped assertions.\n\n### Test File Structure\n\n```yaml\n# $schema: https://raw.githubusercontent.com/helm-unittest/helm-unittest/refs/heads/main/schema/helm-testsuite.json\nsuite: <descriptive suite name>\nvalues:\n  - ../ci/<values-file>.yaml\nset:\n  key.nested: value\ntemplates:\n  - templates/<path-to-template>.yaml\ntests:\n  - it: <test case description>\n    values:\n      - ./values/<scenario>.yaml\n    set:\n      key.nested: value\n    documentSelector:\n      path: metadata.name\n      value: RELEASE-NAME-myapp\n    asserts:\n      - isKind:\n          of: Deployment\n      - equal:\n          path: metadata.name\n          value: RELEASE-NAME-myapp\n      - contains:\n          path: spec.template.spec.containers[0].env\n          content:\n            name: MY_VAR\n            value: my-value\n```\n\n### Scope, Precedence, and Targeting\n\n- Value precedence: chart `values.yaml` < suite `values` < suite `set` < test `values` < test `set`.\n- Template scope precedence: suite `templates` can be narrowed by test `template` / `templates`, then by assertion-level `template`.\n- Document targeting precedence: assertion `documentSelector` / `documentIndex` overrides test-level selector/index.\n- Use `documentSelector` for multi-document templates instead of brittle numeric `documentIndex` when possible.\n- `hasDocuments` ignores selectors by default; set `filterAware: true` to count only selector/index-filtered documents.\n\n### Suite and Test Options\n\n- `release`: exercise behavior that depends on `.Release` (`name`, `namespace`, `revision`, `upgrade`).\n- `capabilities`: pin Kubernetes versions/APIs for branches guarded by `.Capabilities.*`.\n- `chart`: override `.Chart.version` / `.Chart.appVersion` when template output depends on them.\n- `excludeTemplates`: narrow broad template globs to avoid unrelated documents in a suite.\n- `skip`: only for temporary or unreleased behavior; prefer active assertions over skipped tests.\n- `postRenderer`: use only when chart behavior explicitly depends on post-render transforms.\n\n## Testing `lookup` with `kubernetesProvider`\n\nUse `kubernetesProvider` whenever templates call `lookup`; without it, `lookup` returns empty and branch coverage is incomplete.\n\n- Register API kinds in `scheme` using `\"<group>/<version>/<Kind>\"` or `\"v1/<Kind>\"` for core APIs.\n- Each scheme entry must define `gvr` (`group` optional for core APIs, plus `version`, `resource`) and `namespaced`.\n- Provide fixture resources in `objects`.\n- Test-level `kubernetesProvider.objects` can add scenario-specific fixtures without rewriting suite-wide defaults.\n\n```yaml\ntemplates:\n  - templates/lookup.yaml\nkubernetesProvider:\n  scheme:\n    \"v1/Namespace\":\n      gvr:\n        version: \"v1\"\n        resource: \"namespaces\"\n      namespaced: false\n    \"v1/Pod\":\n      gvr:\n        version: \"v1\"\n        resource: \"pods\"\n      namespaced: true\n    \"networking.k8s.io/v1/Ingress\":\n      gvr:\n        group: \"networking.k8s.io\"\n        version: \"v1\"\n        resource: \"ingresses\"\n      namespaced: true\n  objects:\n    - kind: Pod\n      apiVersion: v1\n      metadata:\n        name: exists\n        namespace: default\ntests:\n  - it: should find existing pod through lookup\n    asserts:\n      - isNotNullOrEmpty:\n          path: pod_exists\n      - equal:\n          path: pod_exists.metadata.name\n          value: exists\n  - it: should find test-level object through lookup\n    kubernetesProvider:\n      objects:\n        - kind: Pod\n          apiVersion: v1\n          metadata:\n            name: not-exists\n            namespace: default\n    asserts:\n      - isNotNullOrEmpty:\n          path: pod_not_exists\n      - equal:\n          path: pod_not_exists.metadata.name\n          value: not-exists\n```\n\n## Assertion Guidance\n\n| Assertion | Purpose |\n|---|---|\n| `equal` | Exact match at JSON path |\n| `notEqual` | Value differs from expected |\n| `matchRegex` | Regular expression match on string value |\n| `exists` | Path exists in rendered output |\n| `notExists` | Path is absent from rendered output |\n| `isEmpty` / `isNotEmpty` | Path is empty or not empty |\n| `isNullOrEmpty` / `isNotNullOrEmpty` | Path is null/empty or present with content |\n| `isKind` | Kubernetes resource kind check |\n| `isAPIVersion` | API version check |\n| `contains` | Array/map contains entry |\n| `notContains` | Array/map does not contain entry |\n| `hasDocuments` | Number of YAML documents rendered |\n| `matchSnapshot` | Snapshot testing |\n| `failedTemplate` | Template should fail to render |\n| `notFailedTemplate` | Template should render successfully |\n| `isSubset` | Rendered output is a superset of expected |\n| `lengthEqual` | Array/map length equals expected count |\n\nUse antonym assertions (`notEqual`, `notContains`, etc.) instead of relying on `not: true` unless that is clearer.\n\nPrefer `equal`, `contains`, and specific negative assertions over broad `exists` checks. Specific assertions catch regressions.\n\n### Assertion Scoping Patterns\n\n```yaml\n  - it: targets a single Deployment by name\n    templates:\n      - templates/deployment.yaml\n      - templates/image-renderer-deployment.yaml\n    asserts:\n      - equal:\n          path: spec.replicas\n          value: 1\n        documentSelector:\n          path: metadata.name\n          value: RELEASE-NAME-grafana\n```\n\n```yaml\n  - it: counts only selected docs\n    template: templates/extra-manifests.yaml\n    documentSelector:\n      path: kind\n      value: ConfigMap\n      matchMany: true\n    asserts:\n      - hasDocuments:\n          count: 2\n          filterAware: true\n```\n\n### Multi-Template Safety\n\nIf a suite includes workload templates plus `config.yaml`, set `template` on every assertion unless the test intentionally targets all templates.\n\nPut `template` at the assertion root, not inside assertion parameters.\n\nWrong:\n\n```yaml\n      - notContains:\n          template: backend/statefulset.yaml\n          path: spec.template.spec.containers\n          content:\n            name: loki-sc-rules\n```\n\nCorrect:\n\n```yaml\n      - template: backend/statefulset.yaml\n        notContains:\n          path: spec.template.spec.containers\n          content:\n            name: loki-sc-rules\n```\n\n### Path and jsonPath Guidance\n\n- Prefer precise paths over broad existence checks.\n- When map keys contain dots or slashes, use jsonPath bracket syntax.\n- Keep escaping consistent to avoid false negatives.\n\n```yaml\n  - equal:\n      path: metadata.annotations[\"kubernetes.io/ingress.class\"]\n      value: nginx\n```\n\n### Conditional Rendering Tests\n\n```yaml\n  - it: should not render when disabled\n    set:\n      component.enabled: false\n    asserts:\n      - hasDocuments:\n          count: 0\n```\n\n### Testing with Release Values\n\n```yaml\n  - it: should use release name in labels\n    release:\n      name: my-release\n      namespace: my-namespace\n    asserts:\n      - equal:\n          path: metadata.namespace\n          value: my-namespace\n```\n\n## Test File Organization\n\nMirror the template directory structure:\n\n```text\ncharts/<chart>/tests/\n  deployment_test.yaml\n  service_test.yaml\n  ingester/\n    statefulset_test.yaml\n  compactor/\n    deployment_test.yaml\n```\n\nTest filenames must end with `.yaml`. This repository configures helm-unittest with `--file 'tests/**/*.yaml'`, so any `.yaml` filename is valid. `<template>_test.yaml` is preferred.\n\n## Writing Workflow\n\n1. Read the template being tested. Understand every conditional, value reference, helper call, and document emitted.\n2. Read `_helpers.tpl` and any other helper partials used by the template.\n3. Read `values.yaml` to understand defaults and the full value schema.\n4. Map render targets: determine whether the template emits zero, one, or many documents and which selector is stable.\n5. Write tests for default rendering, significant conditional branches, selector behavior, multi-template scoping, and edge cases.\n6. Run the tests.\n7. Fix failures by adjusting assertions to match actual rendered output.\n8. Repeat until the test file passes.\n\n## Running Tests\n\nRun all charts:\n\n```bash\nmake helm-unittest\n```\n\nRun tests for one chart:\n\n```bash\nmake helm-unittest HELM_CHART=<chart-name>\n```\n\nRun one test file:\n\n```bash\nmake helm-unittest HELM_CHART=<chart-name> HELM_UNITTEST_FILE='tests/<subdir>/<file>_test.yaml'\n```\n\n## Rules\n\n- Only create or edit `.yaml` files under `charts/*/tests/` when this skill is being used specifically to write tests.\n- Do not modify templates, `values.yaml`, `Chart.yaml`, or non-test files as part of a test-writing task unless the user explicitly expands the scope.\n- Never run destructive shell commands.\n- Use `RELEASE-NAME` as the default release name in assertions.\n- Always set deployment-mode-style flags explicitly. Do not rely on defaults when a chart has conditional rendering modes.\n- When a template has subchart dependencies, use `set` to provide required subchart values.\n- Always run relevant helm-unittest commands after writing tests.\n- If a test run reveals the template does not render with default values, inspect `values.yaml` and adjust the test setup.\n- Prefer `documentSelector` over hardcoded `documentIndex` for templates that can reorder output.\n- Use `hasDocuments.filterAware: true` when asserting counts under selector/index filtering.\n- Use `template` / `templates` at test or assertion level to prevent cross-template assertion bleed.\n- For negative paths, assert absence with `notExists` or `notContains`.\n\n<!-- File: .agents/skills/helm-values-schema/SKILL.md (Tokens: ~1181 | Category: anthropic-skill) -->\n---\nname: helm-values-schema\ndescription: Maintain values.schema.json for Helm charts that use helm-values-schema-json annotations in values.yaml.\nuser_invocable: true\n---\n\n# /helm-values-schema [chart]\n\nUse this skill when the user asks to add, change, review, or regenerate a Helm chart `values.schema.json`, or when a chart feature changes `values.yaml` in a chart that uses schema annotations.\n\n## Detection\n\nA chart uses `helm-values-schema-json` if `charts/<chart>/values.yaml` contains either:\n\n- `# @schema` comments\n- a top-level schema reference such as `# $schema: ./values.schema.json`\n\nWhen a chart uses this flow, changes to `values.yaml` must keep schema annotations and `values.schema.json` in sync.\n\n## Documentation\n\nPrefer Context7 for current `helm-values-schema-json` docs when available.\n\nUpstream documentation:\n\n```text\nhttps://github.com/losisin/helm-values-schema-json/blob/main/docs/README.md\n```\n\n## Compatibility\n\nHelm validates chart values with JSON Schema draft-07. Keep generated schemas compatible with draft-07 even if external schema tooling supports newer drafts.\n\n## Workflow\n\n1. Read `charts/<chart>/values.yaml`.\n2. Check whether `# @schema` annotations or `# $schema: ./values.schema.json` are present.\n3. If changing or adding values, preserve nearby annotations and add annotations when inferred schema would be wrong or too loose.\n4. Preserve helm-docs comments. When a field has both `# @schema` and helm-docs `# --` comments, `# @schema` comments must be above the helm-docs description comments.\n5. Regenerate `values.schema.json`.\n6. Review the schema diff for only intentional changes.\n7. Ensure values changes also have helm-unittest coverage for rendered behavior where applicable.\n\n## helm-docs Integration\n\n`helm-values-schema-json` supports using descriptions from `helm-docs` comments since v2.0.0, but only when enabled with `--use-helm-docs`.\n\nExample:\n\n```bash\nhelm schema --use-helm-docs\n```\n\n```yaml\n# -- My description\nfullnameOverride: bar\n```\n\nGenerates:\n\n```json\n{\n  \"fullnameOverride\": {\n    \"description\": \"My description\",\n    \"type\": \"string\"\n  }\n}\n```\n\n### Unsupported helm-docs Features\n\nThe schema plugin does not support helm-docs-specific properties such as:\n\n- `# @default --`\n- `# @section --`\n\nIt also does not support detached helm-docs comments. Comments must be directly above the property or inline in a supported form.\n\nSupported:\n\n```yaml\n# fullnameOverride -- This works\nfullnameOverride: bar\n```\n\nNot supported by the schema plugin:\n\n```yaml\nfullnameOverride: bar\n\n# fullnameOverride -- This does not work for schema generation.\nfullnameOverride: bar\n```\n\nHelm-docs itself does not understand `# @schema` comments. When both `# @schema` and helm-docs comments are above a field, put `# @schema` first so schema annotations are not included in the generated description. Treat the inverse order as invalid: helm-docs will include the schema annotation text in the description.\n\nGood:\n\n```yaml\n# @schema maxLength:10\n# -- My awesome nameOverride description\nnameOverride: \"myapp\"\n```\n\nBad:\n\n```yaml\n# -- My awesome nameOverride description\n# @schema maxLength:10\nnameOverride: \"myapp\"\n```\n\n## Annotation Placement\n\n`# @schema` annotations may be placed inline, on the line above a field, or in specific cases below a block. Preserve the surrounding style already used in the chart, except when the existing style conflicts with helm-docs ordering. If a value has a helm-docs `# --` description, any standalone `# @schema` comments for that value must be above the `# --` comment, never between the helm-docs comment and the value.\n\nExamples:\n\n```yaml\nfullnameOverride: \"myapp\" # @schema maxLength:10;pattern:^[a-z]+$\n\n# @schema maxLength:10;pattern:^[a-z]+$\nnameOverride: \"myapp\"\n\n# @schema maxLength:10\n# -- My awesome nameOverride description\nnameOverride: \"myapp\"\n\n# Invalid with helm-docs: the schema annotation becomes part of the description.\n# -- My awesome nameOverride description\n# @schema maxLength:10\nnameOverride: \"myapp\"\n\nresources:\n  limits: {}\n  requests: {}\n# @schema additionalProperties:false\n```\n\nMultiple schema annotations can be separated with semicolons.\n\n## Commands\n\nFor Loki, use the repository target:\n\n```bash\nmake helm-schema HELM_CHART=loki\n```\n\nThe underlying command currently runs:\n\n```bash\nhelm schema --config .github/linters/.schema.yaml -f charts/loki/values.yaml -o charts/loki/values.schema.json\n```\n\nIf adding schema generation for another chart, follow the chart's local Makefile or CI pattern instead of inventing a one-off command.\n\n## Rules\n\n- Do not hand-edit `values.schema.json` when it can be regenerated.\n- Do not remove existing `# @schema` annotations unless the associated value is removed.\n- Keep schema annotations as close as possible to the value they describe.\n- Keep `# @schema` comments above helm-docs `# --` comments. Never add a standalone `# @schema` comment below a helm-docs description comment for the same value.\n- Include regenerated `values.schema.json` in the change.\n- Values changes that affect rendered manifests should also be covered by helm-unittest tests.\n\n<!-- File: .github/copilot-instructions.md (Tokens: ~240 | Category: copilot-instructions) -->\n# GitHub Copilot Instructions\n\nFollow the repository-wide agent guidance in `AGENTS.md`. This repository contains Helm charts for Prometheus ecosystem components.\n\nMost tasks are Helm chart feature changes. When changing a chart:\n\n- Work within a single chart under `charts/<chart>/`.\n- Read `Chart.yaml`, `values.yaml`, relevant templates, helpers, and existing tests before editing.\n- Follow existing chart patterns before adding new structure.\n- Update `values.yaml`, templates, tests, and generated schema artifacts together when a new value changes rendered behavior.\n- If `values.yaml` contains `# @schema` comments or `# $schema: ./values.schema.json`, follow the `helm-values-schema` skill guidance and regenerate `values.schema.json`.\n- Add or update helm-unittest coverage for rendered behavior changed by templates or values.\n- Run `helm unittest --strict --file 'unittests/**/*.yaml' charts/<chart-name>` for charts with helm-unittest coverage.\n- Bump the chart version in `Chart.yaml` for chart changes not ignored by `.helmignore`.\n- Do not edit generated ownership files such as `.github/CODEOWNERS` or `MAINTAINERS.md` directly.\n</yakaai_skills>"}