What the agent does
The agent checks out the pull request's branch in its own sandbox and reads how the repository tests charts before it runs anything. In a repository like prometheus-community/helm-charts, .github/workflows/ci.yaml pins Helm v4.3.1 and chart-testing v3.15.0, and .github/linters/ct.yaml sets target-branch: main, chart-dirs: [charts], excludes prometheus-to-sd, and adds two commands that ct lint runs on every changed chart: ci/lint.sh through shellcheck when a chart has one, and helm unittest --strict --file 'unittests/**/*.yaml'. The agent installs the same versions and the helm-unittest plugin so its results match what CI will report.
Then it runs ct list-changed and ct lint --config .github/linters/ct.yaml, which fails on a chart whose version in Chart.yaml was not bumped against main, plus helm lint and the unit tests. For kube-prometheus-stack that means the suites under unittests/ (alertmanager/, prometheus/, grafana/, node_selector_test.yaml, route_test.yaml and more), and every values file under the chart's ci/ directory, such as 03-non-defaults-values.yaml and 07-arbitrary-fs-access-deny-values.yaml, which CI also uses as its install matrix.
Linting passes on plenty of changes that still break an upgrade, so the agent renders the chart twice. It runs helm template on the main version and on the pull request's version with the default values.yaml and with each ci/*-values.yaml, and diffs the output, the same comparison the repository's CI makes with helm diff upgrade --normalize-manifests against a kind cluster. A change to spec.selector.matchLabels on a Deployment or DaemonSet is the classic finding: selectors are immutable, and REVIEW_GUIDELINES.md says helm.sh/chart must never appear there because the next upgrade fails.
Last, it reads the diff against the repository's own checklist. REVIEW_GUIDELINES.md asks that resources are not set by default, that persistence, ingress and autoscaling are off by default, that a breaking change bumps the major version and adds a section under the README's ## Upgrading heading, and that each chart has tests. The chart's UPGRADE.md shows the expected style: the 91.x to 92.x entry explains that a new default nodeSelector restarts Prometheus, Alertmanager and the operator once. The agent posts one review with file and line for each finding and the rendered manifest lines that show it.
Start it with one API call
POST https://api.prix.dev/o/{org}/sessions with this body:
{
"agent": "claude",
"input": "Review the open pull request on this Helm chart repository. Install the Helm and chart-testing versions the CI workflow pins, then run ct lint with the repository's ct.yaml, helm lint and helm unittest for every changed chart. Render each changed chart with helm template on main and on this branch, with values.yaml and each file in the chart's ci/ directory, and diff the output. Post one review that cites file and line for every finding, covering template logic, changed values defaults, selector or other immutable field changes, a missing version bump, and breaking upgrades without upgrade notes. Do not push commits.",
"resources": [
{
"url": "https://github.com/your-org/your-charts/pull/123"
}
]
}- Get an API key. In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
- Send the request. POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
- Read what came back. Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.
What comes back
What comes back is one review on the pull request. Comments sit on the changed lines of templates/*.yaml, values.yaml or Chart.yaml, and each one quotes the rendered manifest that shows the problem: the Deployment whose selector changes, the container that now gets a resources block by default, the value whose new default turns on a ServiceMonitor or a PersistentVolumeClaim for every existing install. The summary lists each command it ran per chart and per values file.
The session keeps the evidence: the ct lint output with the version check, the helm-unittest results per suite, and the rendered diff between main and the branch for each values file. A reviewer can see from those whether a finding came from a failing test, a lint rule or only from the rendered output.
Before merging, a maintainer checks that the version bump matches the size of the change (a major for anything that needs a manual step), that the upgrade notes say what restarts and what users must change, and that new defaults stay off unless the chart has always shipped them on. A selector or StatefulSet volume claim change is the finding to resolve before anything else.
Run it on every chart pull request
An automation with a GitHub trigger on pull_request.opened and pull_request.synchronize runs this review on each push, which suits a chart repository where most pull requests are small version bumps from Renovate and a few change templates. From your own server, receive GitHub's pull_request webhook and send this body with the pull request URL in resources and the head SHA as the Idempotency-Key.
A key runs at most max_concurrent sessions at once, 4 by default, and answers 429 past that, so a burst of dependency pull requests should be queued by your server. Set a webhook URL on the key and each run.completed tells you which review is posted.
The use case this job follows, with its automation and trigger: Review every pull request.
Why run it on Rush?
Reviewing a chart properly means installing the right Helm and chart-testing versions, the unittest plugin, and rendering two versions of the chart with several values files, then reading a long diff. That is a lot of setup to repeat for every pull request on a laptop, and it is why many chart reviews only read the template diff. On Rush each review runs in its own sandbox with those tools installed for that run, with no kube context and no cluster access, so a wrong render cannot touch anything.
The output is a review with the evidence attached. Every comment points to the rendered lines or the failing test in the session's transcript, so a maintainer can trust a selector finding without re-running helm template themselves. Reviews of pull requests to different charts run at the same time, each isolated from the others.
Frequently asked questions
Does it need a Kubernetes cluster?
No. ct lint, helm lint, helm unittest and helm template all run without a cluster, and the upgrade comparison is a diff of rendered output from main and the branch. If you want an install check as well, ask for a kind cluster in the prompt and the agent creates one inside its sandbox.
Will it catch a missing chart version bump?
Yes. ct lint compares each changed chart's version in Chart.yaml with the target branch set in ct.yaml and fails when it was not bumped. The review also says whether the bump fits the change, for example a patch bump on a change that alters a selector.
What about charts with subcharts?
The agent runs helm dependency update before rendering, as the repository's CI does for kube-prometheus-stack with its grafana, kube-state-metrics and node exporter subcharts. A change to a subchart's version shows up in the rendered diff like any other change.
Does it check values.schema.json?
When a chart ships a values.schema.json, helm lint validates the values files against it, and the agent comments if a new value is missing from the schema. In prometheus-community/helm-charts seven charts carry one and the CI installs a schema plugin to keep it in step.