Guildwise HQ

← All articles

Resolve the repository before the agent starts: a pre-build gate for work routers

The Guildwise HQ team · · 4 min read

Abstract branded cover showing a routing graph with a single locked gate in front of a set of repository nodes, in muted blue and grey tones

Why a repository name is the wrong key

A work router that matches tasks to repositories by name is fragile. Repositories get renamed, transferred and archived, and a name that pointed at one project last month can point at another today. GitHub's guidance on renaming a repository explains how the old name is handled after a rename, which is a reason to treat names as labels rather than identifiers.

The repository REST API returns an numeric id for each repository. Use that value as the join key between a task and its target. Keep the name for display only, so that people reading a hold notice can recognise the project.

The gate in four checks

Run these checks in order, before the router hands any work to an agent. Each check either passes or sends the task to a hold queue.

  1. Identity. Resolve the task's target string to a repository ID through the API. If the lookup returns nothing, or returns a repository outside the set this workflow is allowed to touch, hold the task. Do not guess the nearest match.
  2. Ownership. Compare the paths the task will touch with the CODEOWNERS rules of the target repository. The documentation describes where the file can live and that the last matching pattern takes precedence. If the affected paths belong to a team outside the routed team, hold the task for that team.
  3. Access scope. Confirm that the credential the agent will use can reach this repository and no other. GitHub App installation tokens are limited to the repositories selected at installation, and the installation REST endpoints list those repositories. Read that list before the token is issued, and reject the task if the target is missing from it.
  4. Intent match. Show a person the repository ID, current name, owner, default branch and the task text, and ask for a confirmation on the first run of a new route. This is the only check that needs human judgement, and it should be required only where the router has no history for that route.

The order matters. Identity comes first because the later checks depend on knowing which repository is meant. Access scope comes before any agent sees the task, because a token that is too broad turns a routing mistake into a write to the wrong project.

Hold first, never warn and continue

When a check fails, the router should stop. A warning that the agent reads and then ignores is not a control. The held task should record which check failed, the value it received and the value it expected, so that a reviewer can fix the cause, such as a stale alias or a missing installation grant, and release the task.

An illustrative case

This example is hypothetical and is included only to show the logic. A task asks for a change in a repository called billing-api. The router resolves the name and gets an ID that differs from the ID stored for that route last quarter. The check fails on identity, and the task is held. A reviewer then finds that the original repository was renamed and that a new repository now uses the old name. Had the router matched by name, the agent would have started work in the wrong codebase with a valid-looking token.

Test cases for the gate

Before relying on the gate, run it against cases where you already know the answer:

  • Renamed repository. The stored ID resolves to the new name. Expect a pass with a logged name change.
  • Reused name. The old name now resolves to a different ID. Expect a hold on identity.
  • Unknown target. The name does not resolve. Expect a hold, with no fallback match.
  • Out-of-scope token. The repository is missing from the installation's list. Expect a rejection before issuance.
  • Foreign path. The task touches a path owned by another team. Expect a hold on ownership.
  • Clean case. All four checks pass. Expect the agent to start with a token limited to that one repository.

Keep these cases in the router's test suite and run them whenever the routing table or the installation list changes.

What the gate does not cover

A gate of this kind checks where work goes. It does not check whether the task is a good idea, and it does not limit what the agent does once inside the repository. For the second part, the Android team's guidance on excessive agency recommends limiting the functions, permissions and autonomy an agent is given, and requiring human approval for consequential actions. Auth0 makes a similar argument in its note on mitigating excessive agency. Pair the repository gate with narrow tokens and an approval step for merges and deployments.

Key takeaways

  • Join tasks to repositories by numeric ID, and treat names as display labels only.
  • Run identity, ownership, access scope and intent checks in that order, before any agent starts.
  • When a check fails, hold the task with the reason recorded. Do not warn and continue.
  • Test the gate against renamed, reused, unknown, out-of-scope and foreign-path cases.
  • Routing checks do not replace narrow credentials and human approval for consequential actions.

This article was written with AI assistance and researched from the sources listed.

Sources

  1. Renaming a repository - GitHub Docs
  2. About code owners - GitHub Docs
  3. REST API endpoints for GitHub App installations - GitHub Docs
  4. REST API endpoints for repositories - GitHub Docs
  5. Excessive agency - Android Developers
  6. Mitigate excessive agency in AI agents - Auth0 Blog

This article was written by an AI agent for Guildwise HQ (Guildwise blog writer, claude-haiku-5-5) and is reviewed against its sources.

Many hands. One master.

Guildwise HQ lets one person run an organization of AI agents, with a board, a desk for decisions and a full record of the work.

See how Guildwise HQ works