How to route GitHub mentions by repository

Add one github.yaml to your .ellipsis repository to pick which agent answers @ellipsis in each repository, with its own prompt, token scope, sandbox, and budget.

@ellipsis in a pull request or issue comment always gets an answer: with no configuration, the built-in responder reads the thread and replies. One file makes that answer yours: github.yaml in your .ellipsis repository names an agent per repository, each with its own prompt, GitHub token scope, environment, and budget.

Prerequisites: the GitHub App installed on the repositories you want to route, plus a repository named .ellipsis in your organization.

ellipsis:
  version: v1
  kind: github
  name: GitHub agents

environment: cloud_agent_environment

agents:
  - name: web
    github:
      repositories: [web-repo]
    claude:
      system: |
        You answer @ellipsis on pull requests and issues in the web app.
        Ground every answer in the code in front of you: cite files and
        functions, never guess. When asked for a change, make it on the
        PR's branch and push.
    budget: 2.00

  - name: everything-else
    github:
      repositories: ['*']
    claude:
      system: |
        You answer @ellipsis across the organization's repositories. Read
        the code before you answer, and keep replies short.
    permissions:
      github:
        permissions: read_only
    budget: 1.00

Commit that to .ellipsis/github.yaml and it is live when it merges to that repository's default branch. web-repo now gets an agent that pushes fixes; every other repository gets one that reads with a read-only token and cannot push.

Where the file goes, and why only one

github.yaml is read from your .ellipsis repository only, at one of .ellipsis/github.yaml, ellipsis/github.yaml, .agents/github.yaml, or agents/github.yaml. A copy in any other repository is ignored.

The file routes by repository, so a per-repository copy could only ever say "this repository: this agent", and two copies could disagree with nothing to choose between them. One file, one place: reading your routing is opening one file.

Routing per repository

Each agent's github: block lists the repositories it answers in, by bare name (web-repo, not your-org/web-repo; the your-org/ prefix is accepted and ignored). Names are matched case-insensitively.

'*' claims every repository. A named repository beats '*', and each repository may be claimed by exactly one agent: a file where two agents claim web-repo, or two agents claim '*', is rejected, because the alternative is your routing silently depending on which one we happened to pick.

A repository nobody claims still gets an answer: the built-in responder handles it, so @ellipsis never goes silent in a repository you forgot to list. You can never lose that floor, only override it.

What the agent sees

The mentioned pull request or issue is the conversation, and every mention on it continues the same durable conversation: the agent keeps what it already said and did as context, and a follow-up mention lands in the same session with the working tree intact. A 👀 reaction on your comment acknowledges it while the session works.

The sandbox clones the mentioned repository at the pull request's head, plus whatever environment.repositories declares. A file-level environment: block or a saved environment name is inherited by every agent, and an agent's own environment: overrides it field by field; an environment named by reference wins whole.

Lock an agent down with a read-only token

Any agent can be narrowed to a token that cannot write, as everything-else is above:

agents:
  - name: everything-else
    github:
      repositories: ['*']
    permissions:
      github:
        permissions: read_only

The restriction is enforced by GitHub at the moment the token is minted, so nothing running in the sandbox can exceed it. A read-only agent still answers every question; it cannot push, merge, or open pull requests.

Budgets and spend

Each agent's budget caps a single conversation's cumulative spend across its turns, in USD; omit it and the conversation inherits your account's default session budget. Details in Budgets.

When the file is wrong

Validation is strict and the file is checked on every push to your .ellipsis default branch: an unknown field, a repository claimed twice, or two '*' agents is a sync error you see in the dashboard.

A file that fails to parse does not take your routing down. The last version that parsed keeps routing until you fix the new one, so a typo costs you the change, not the organization.

Next

Slack channels and DMs route from slack.yaml: Build a custom Slackbot. Linear teams and projects route from linear.yaml: Route Linear mentions.

On this page

Schedule a demo