All jobs

Add Resource Requests and Limits to a Kustomize App from a Linear Issue

Yes. An agent reads the issue, finds every container in your Kustomize app without resources, adds requests and limits, validates the render and opens a PR.

Run this on RushIn a Project that has your repository.

What the agent does

The agent starts from the Linear issue and the repository in its own cloud sandbox, and takes an inventory before it edits a manifest. In a GitOps repository shaped like argoproj/argocd-example-apps, sock-shop/kustomization.yaml lists 29 files under base/: 14 Deployments, 14 Services and one Ingress for sockshop.apps.argoproj.io. Eight of the Deployments already carry a resources block, and they are not uniform: carts, queue-master and shipping ask for and cap at 300m CPU and 500Mi memory, catalogue at 100m and 100Mi, front-end requests 100m and 300Mi under limits of 300m and 1000Mi, orders requests 200m under a 500m limit, payment requests 99m under 100m, and user requests 100m CPU under 300m with 100Mi both ways. The other six have none: carts-db, orders-db and session-db (the mongo and redis:alpine images), catalogue-db, user-db, and rabbitmq, which also runs a kbudde/rabbitmq-exporter sidecar with no resources of its own, so there are seven containers to change. The smaller kustomize-guestbook app has one Deployment of gcr.io/google-samples/gb-frontend:v5 with nothing set either.

The agent then decides where the change goes. sock-shop has no overlays; its kustomization.yaml names the base files directly, so a patches block would be a second place to look for a value that belongs in one. It edits each Deployment under sock-shop/base/ in place and keeps the diff to the resources block. Where an app does have overlays, as kustomize-guestbook would after a staging overlay is added, it writes a strategic merge patch in the overlay instead, so the base stays environment-neutral. The values come from the issue when it gives them; when it gives none, the agent starts each container at the smallest tier already in the app, 100m CPU and 100Mi memory as catalogue and payment use, with requests equal to limits so the pod lands in the Guaranteed QoS class like carts and shipping, and the pull request says plainly that these are starting points to be tuned from metrics, not measured numbers. For carts it also notes the existing JAVA_OPTS of -Xmx128m against a 500Mi limit, since the heap cap and the container cap should be read together.

Then it renders and checks. kustomize build sock-shop must still produce all 29 resources with the new blocks in place and nothing else changed, and the agent diffs that output against a build of the base branch to show the change is only what it meant. It runs kubeconform -strict -summary over the rendered YAML so a misplaced key such as resources at the pod level rather than the container level is caught, and where a kind cluster is available in the sandbox it applies the output with kubectl apply --dry-run=server to let the API server validate the quantities. The repository has no CI of its own, so these three commands are the checks, and their output goes into the pull request.

The pull request also carries a table: one row per container, with the image, the requests and limits before and after, and the QoS class the pod will get. Containers that were already set are listed as unchanged, so a reviewer sees the whole app, not only the diff.

Start it with one API call

POST https://api.prix.dev/o/{org}/sessions with this body:

{
  "agent": "claude",
  "input": "Add resource requests and limits to the Kustomize app the attached Linear issue names. Read its kustomization.yaml and every Deployment it lists, including sidecar containers, and build a table of which containers already have a resources block and which do not. Add requests and limits to the ones without: use the values the issue gives, and when it gives none, start from the smallest tier already present in the app with requests equal to limits, and say in the pull request that they are starting points. Edit the base files in place when the app has no overlays, otherwise add a strategic merge patch in the overlay. Run kustomize build on the app, diff the output against the base branch to show only resources blocks changed, run kubeconform -strict -summary on the rendered output, and apply it with kubectl --dry-run=server if a cluster is available. Open a pull request linking the issue with the before and after table, the QoS class per pod and the command output. Do not change images, replicas or probes.",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    },
    {
      "url": "https://linear.app/your-org/issue/ENG-123"
    }
  ]
}
  1. 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.
  2. 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.
  3. 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 a pull request on its own branch that touches only the Deployment files for containers that had no resources block, in sock-shop/base/ six files covering seven containers. The description links the Linear issue, carries the per-container table with the before and after values and QoS class, and quotes the kustomize build diff summary, the kubeconform summary line and, when a cluster was available, the dry-run output.

The transcript at GET /o/{org}/sessions/{id}/messages keeps each kustomize build, the diff and the validation runs with their full output, and GET /o/{org}/p/{project}/sessions/{id}/changes lists each changed file with its diff. A rendered output that fails validation ends the run needs_review instead of a pull request that claims the manifests are valid.

Before merging, a reviewer checks the starting values against what the cluster's metrics show for those pods, confirms no LimitRange or ResourceQuota in the target namespace rejects them, and reads the rabbitmq change twice because that pod has two containers. Argo CD picks the change up on sync; a follow-up on the same session can raise a value once the first sync has run for a day.

Run it on every Linear issue labelled agent

In the console, add an automation to the Project with this prompt and a linear trigger on linear.issue.labeled, filtered to the agent label and to the platform team. When someone labels an issue such as "sock-shop databases have no resource limits, pods get evicted first under pressure", the trigger puts the issue after the prompt and the run scopes itself to the app the issue names, with the values it gives. Only label changes made by a person in your Rush org fire the trigger, and the automation starts at most max_runs_per_hour runs in an hour.

From your own server, the same body goes to POST /o/{org}/sessions with the repository in resources and the issue's URL beside it, read through your Linear connection, and a request_id made from the issue id so a retried call returns the run already started rather than opening a second pull request.

The use case this job follows, with its automation and trigger: Turn a Linear label into a PR.

Why run it on Rush?

Resource blocks are easy to type and easy to put in the wrong place, and a GitOps repository with no CI finds out at sync time. In its own sandbox the agent renders the app with the same kustomize Argo CD runs, validates the output with kubeconform, and keeps the diff against the base branch, so the pull request shows that the only change is the one the issue asked for.

Several apps can run at once, each in a separate sandbox and a separate pull request, and every command is in the transcript. A reviewer who wants to know why a value was chosen reads the table and the issue, not a commit message.

Frequently asked questions

Where do the numbers come from?

From the Linear issue when it gives them. When it does not, the agent uses the smallest tier already present in the same app, which in sock-shop is 100m CPU and 100Mi memory, sets requests equal to limits, and marks them as starting points in the pull request. It invents no figures from the images, and the reviewer is expected to adjust them from metrics.

Does it edit the base or add a patch?

It depends on the app's layout. sock-shop lists its base files directly in kustomization.yaml with no overlays, so the agent edits the Deployment files and the diff stays readable. An app with overlays gets a strategic merge patch in the overlay, so the base stays free of environment-specific numbers.

What about sidecars?

A Deployment is checked per container, not per pod. In sock-shop/base/rabbitmq-dep.yaml the rabbitmq-exporter sidecar has no resources block even though it sits next to the main container, so it gets its own block and its own row in the table.

Can it validate without a cluster?

Yes. kustomize build and kubeconform -strict run with no cluster and catch schema and placement mistakes. The kubectl apply --dry-run=server step runs only when a kind cluster is available in the sandbox, and the pull request says which of the three checks ran.