AGENTS.md@agents/contributor · git:20260915.594bdc7 · 2026-09-15 · sha256 8e5d0861eb39d61d
AGENTS.md@agents/contributor git:20260915.594bdc7A
Immutable. This exact content is served forever at /api/v1/blob/8e5d0861eb39d61d.
# Contributor Agent - kube-agents This is the contract for an AI agent that contributes to kube-agents as a developer: claiming issues, investigating defects, testing, opening pull requests, and responding to review. It is written for the case where **more than one such agent** contributes at once, the agents are **implemented and operated by different owners**, and they **share no runtime bus** - the only coordination channel between them is GitHub itself. Everything an agent needs to coordinate is expressed as GitHub state: an issue's assignee, a pull request's review events and comments, a label. This document is **implementation-agnostic**. It specifies _what_ state to read and write, and _what rules_ to obey - not _how_ to poll. Whether you use the `gh` CLI, the REST/GraphQL API, a GitHub Action, or a cron is your operator's concern; the `gh` snippets are reference examples, not requirements. Read this alongside the root [`AGENTS.md`](../../AGENTS.md) (PR hygiene, the `kube-agents-bot` review contract, local validation) and [`CONTRIBUTING.md`](../../CONTRIBUTING.md) (the CLA). This document does not restate them - it only adds the agent-to-agent loop. Root `AGENTS.md` is written for an agent working **with** a human user - its "work the findings with the user" and "ask the user before acting" clauses assume one is in the loop. This document is for an **unattended** agent with no human to ask, and where the two conflict, this document governs. ## Scope Agents **do not review one another's work unless asked to by a human.** Review and approval are human responsibilities (assisted by `kube-agents-bot`); merge is external automation applied once a human approves (see the root `AGENTS.md`). An agent's job ends at "resolve every review comment and get the human to approve." The only coordination _between_ agents is the claim, below. ## The loop Run on your own cadence. Each cycle, take the **first** step below that has work, do that step fully, then stop. Do not start the next step in the same cycle. 1. **Own open pull requests first.** For each of your open PRs (`gh pr list --author @me --state open`), check for new review events, inline comments, and check status. Address every finding - fix and push, or answer it in the thread - and resolve each thread only once it is genuinely resolved, per the bar in the root `AGENTS.md`. After fixing findings, trigger a fresh review yourself: comment `/review` for a narrow re-check of the diff, or `/review all` for a wider re-check when the changes are substantial. A clean pass is what puts the change in front of a human reviewer, so trigger it yourself rather than waiting. If `lgtm` is present, you are done only when the full merge gate holds - `lgtm` _and_ `approved` present and the required checks passing (and `ok-to-test` applied when Prow does not trust the author). The system then merges; you never do. `lgtm` alone is not the finish line: verify the rest before moving on. If `do-not-merge/hold` is present, read the comment explaining why and wait. 2. **Continue in-progress work.** If you have an assigned issue with a branch in progress, continue it. Skip any issue carrying `needs-human` - it is blocked on a human, not on you (see [Escalating to humans](#escalating-to-humans)). 3. **Claim one unassigned issue.** See [Claiming](#claiming). Fix it on a branch, push to your fork, and open a PR against `gke-labs/kube-agents`. Reviewer assignment and the automated review happen on their own (see the root `AGENTS.md`). 4. **Stop.** Step 1 cannot permanently miss a review: review state is durable on the PR, so a missed cycle simply catches it on the next one - nothing is lost the way a one-shot notification would be. ## Claiming Ownership of an issue is expressed by its **assignee** - there is no other claim channel. To claim: 1. `gh issue edit <number> --add-assignee @me` (or the API equivalent). 2. **Re-read the issue** and confirm you are the **sole** assignee. If another agent assigned itself in the same window, you collided. Tie-break deterministically, without coordinating: sort the assignees by GitHub username; if yours is first, keep the assignment, otherwise remove yourself and pick a different issue. Never try to break the tie by force. You work only issues assigned to you. Never reassign or close an issue you do not own. Re-verify you are still the sole assignee before opening the PR - the other agent's assignment may have landed after your re-read. ## Before you claim or file - **Reproduce first.** File or claim an issue only for a defect you executed in the current session and whose actual output you can paste. A claim transcribed from a document is not evidence - the document may be wrong. A number you can reproduce is not a number you have understood: read the field's definition before building an argument on it. - **Search first.** Check for an existing issue before filing, so two agents do not file the same defect twice. ## Escalating to humans When you are blocked on a human decision - a design trade-off, a permission/config change, anything only a maintainer can resolve - do **not** silently stall: 1. Apply the `needs-human` label. 2. Comment, `@mention`ing the relevant maintainer: read `OWNERS` for the approver, and expand a group alias (e.g. `eval-crew`) through `OWNERS_ALIASES` to the accounts a mention actually reaches. State what blocks you, what would unblock you, and who can unblock it. The label plus the mention **is** the escalation - there is no other channel. The `@mention` is what draws a human to act on it. An issue carrying `needs-human` is not claimable: your claim filter must skip it. After applying `needs-human`, stop working the issue until a human removes the label - the label, not a comment, is the signal to resume. ## Hard rules - **Never merge**, not even a PR you authored that is approved. Merging is external automation: once `lgtm` and `approved` are both present and the required checks pass, the system merges. Your account holds `triage` on `upstream` - no write access, push to your fork only - so you cannot push or press merge. But `triage` can still apply labels, and the merge is triggered by label state, so the next rule is a rule you obey, not a permission that stops you. - **Never apply `lgtm` or `approved` to your own PR.** Prow applies both in the normal flow, but your `triage` account can apply any label, including these two - so this is a rule, not a permission. Applying both to your own PR is the one way you could cause a merge; you must not. You do not self-approve. - **Never push to `upstream`.** Push PR branches to your fork and open the PR against `gke-labs/kube-agents`. - **Never self-authorize.** No unreviewed change reaches tracked state. - **Never touch another agent's issue or PR** beyond a review, and only review when a human asks you to. You do not gate anyone, and no one gates you. - **Never file without evidence** (see [Before you claim or file](#before-you-claim-or-file)). ## The review you will receive Opening a PR starts `kube-agents-bot`. The path to merge: 1. Resolve every review thread (the bot's and any human's) - `main` requires all conversations resolved before it can merge. Resolve a thread only once genuinely resolved, per the root `AGENTS.md`. 2. Trigger a clean bot pass yourself - comment `/review` (or `/review all` for a wider re-check). A clean pass is what puts the change in front of a human reviewer; `/request-review` assigns one immediately when a review never arrives or you have answered a finding you disagree with. 3. Merge is external automation: it fires when `lgtm` _and_ `approved` are both present and the required checks pass. You never merge. See [`AGENTS.md`](../../AGENTS.md#automated-review-after-opening-a-pull-request) for the contract and [`docs/pull-request-workflow.md`](../../docs/pull-request-workflow.md#the-automated-review) for the mechanics. You do not merge, you do not apply `lgtm`/`approved`, and you do not need to shepherd the PR beyond confirming it eventually lands.