What changes when a task spans more than one repository

A coding agent working inside a single git checkout has a genuinely easy job by comparison: it can grep the whole tree, follow an import to its definition, and trust that anything it sees on disk is the current, canonical version. None of that holds once a task needs a services repo, the shared library that repo imports, and the infra repo that deploys it. The agent's context window still has room for the work; what it is missing is a map of where the rest of the truth lives.

  • Context windows are not the bottleneck most teams think they are. Even a modest context window comfortably holds a manifest, a repo map and the working set for one repo. The bottleneck is that nobody told the agent a second and third repo exist.
  • Cross-repo symbol resolution has no default answer. An import inside one repo resolves against a package registry or a version pin, not against source the agent can open and read — unless you give it a local checkout.
  • Stale mental models compound across a session. An agent that read the shared-library repo once at the start of a long session has no signal that a teammate merged a breaking change to it twenty minutes later.
  • Single-repo defaults are baked into the tooling. Launch most coding agents from inside one checkout and that is the entire universe they reason about, by design — it is a sane default, not a limitation you can prompt your way around.
Pro tip

Before you ask an agent to touch a cross-repo task, ask it to read a manifest first — not to explore. "Read workspace.yaml, tell me which repos this task touches and why, then wait" costs a handful of tokens and turns a blind multi-repo task into a scoped one. Exploration-first is where most of the wasted turns and stray edits in multi-repo work come from.

Why agents default to single-repo assumptions

It helps to be specific about where multi-repo work actually breaks down, because "the agent got confused" is not an actionable diagnosis. Three failure patterns show up repeatedly, whether the team is a fintech in Bangalore shipping a payments platform or a scale-up in London running a customer-support product.

The agent cannot see what it has not been given. A coding agent's working context is whatever is on disk in its working directory (or worktree) plus whatever you paste or link in. If the shared library lives in a sibling repository the agent was never pointed at, it is not "missing context" in the abstract — it has zero information that repository exists. Ask it to add a field to a shared type and, absent any signal otherwise, it will either invent a local copy of that type or silently skip the parts of the task it cannot see.

Cross-repo symbol resolution is genuinely unsolved by default. Inside a single repo, "go to definition" is a solved problem — language servers and simple text search both work. Across repos, the equivalent question — "where is RefundRequest actually defined, and is this repo's copy of it current?" — has no built-in answer unless the dependency is checked out locally or a graph tool has indexed it. Teams building code-graph and cross-repository navigation tooling (Sourcegraph's cross-repository code intelligence is a well-known example) exist specifically because this gap is real, not imagined.

Stale mental models are a session-length problem, not a one-off. An agent forms its understanding of a dependency at the moment it reads it. In a fast-moving codebase with several contributors — human and agent — pushing to the shared repo through the day, that understanding ages the moment it is formed. The longer a session runs, the larger the gap between what the agent believes about a dependency and what is actually merged.

Watch out

An agent that cannot see a repo does not fail loudly. It fails by producing something plausible — a re-declared type, a duplicated helper, a call against an API shape that changed last week. These pass a casual review because they compile and read cleanly. Budget real review time for anything a cross-repo task touches outside the repo the agent started in.

Read the manifest first: dependency graphs, repo maps and index files

The single highest-leverage thing you can do for multi-repo agent work is give the agent something to read before it starts exploring: a small, explicit manifest describing which repos exist, what each one owns, and how they depend on each other. This is not a new invention — it is the repository-level equivalent of the AGENTS.md and CLAUDE.md files that already steer agents inside a single repo, just scoped one level up.

Keep the manifest in a lightweight, version-controlled location everyone on the task can see — an umbrella repo, a docs repo, or even a top-level file in whichever repo most often kicks off cross-cutting work. A minimal version looks like this:

# workspace.yaml — the single source of truth for how these repos relate
workspace: payments-platform

repos:
  - name: payments-api
    path: ../payments-api
    role: service
    owns: ["REST endpoints", "billing domain logic"]
    depends_on: ["shared-types", "platform-infra"]

  - name: shared-types
    path: ../shared-types
    role: library
    owns: ["TypeScript contracts", "OpenAPI schema", "published package @acme/shared-types"]
    depends_on: []

  - name: platform-infra
    path: ../platform-infra
    role: infra
    owns: ["Terraform modules", "CI pipeline definitions", "environment config"]
    depends_on: []

That file answers the three questions an agent otherwise has to guess at: which repos exist, what each one is responsible for, and which direction the dependencies point. For a task like "add a refund reason code", reading this manifest first tells the agent in one pass that it needs shared-types for the contract, payments-api for the handler, and probably not platform-infra at all — a scoping decision that would otherwise cost several exploratory turns.

A manifest like this is deliberately coarse — repo and dependency level, not file level. Inside each repo, pair it with a finer-grained index. Aider's repository map is a useful reference point here: its own documentation describes building a graph where source files are nodes and dependency edges connect them, then ranking that graph to surface the files and symbols most relevant to the current request within a token budget, rather than dumping the whole tree into context. Several monorepo build tools — Nx and Turborepo among them — expose a comparable project graph that an agent can query directly for "what depends on what" instead of grepping for imports. The pattern is consistent across all of them: a small, structured index beats an agent inferring structure from raw file contents, and it beats it on both accuracy and token cost.

Recommended

Treat the manifest as code: review changes to it the way you would review a schema migration, and update it in the same pull request that adds or removes a repo dependency. A manifest that lags reality is worse than no manifest — see the pitfalls section below.

Workspace and worktree patterns: give the agent one view across repos

Once the agent knows which repos a task touches, it needs local, readable copies of all of them at once — not a description of them. This is where workspace layout and worktrees do the actual work.

Umbrella workspace directories and worktrees

The simplest pattern is a scratch directory, named after the task, that holds a worktree of every repo the task touches, all checked out to matching branch names. This is tool-agnostic — it works whether the agent driving it is Claude Code, Cursor, Copilot Workspace or a custom harness — because it is just git:

# one directory per task, one worktree per repo the task touches
mkdir -p ~/tasks/add-refund-reason-code
cd ~/tasks/add-refund-reason-code

git -C ~/repos/payments-api    worktree add ./payments-api    -b feat/refund-reason-code
git -C ~/repos/shared-types    worktree add ./shared-types    -b feat/refund-reason-code
git -C ~/repos/platform-infra  worktree add ./platform-infra  -b feat/refund-reason-code

Point the agent's working directory at ~/tasks/add-refund-reason-code and it can now read, edit and test across all three repos in one session, on branches that are easy to find and easy to discard. Each repo keeps its own history and its own remote, so nothing about your repository topology has to change.

As of mid-2026, Claude Code's documented --worktree flag and its EnterWorktree tool automate this same worktree-per-branch pattern for a single repository, and a custom subagent can request its own isolated worktree by setting isolation: worktree in its frontmatter, per Anthropic's worktree documentation. That built-in isolation is genuinely useful once the agent is inside one repo; for the multi-repo case it is still your umbrella directory, built with plain git worktree commands, that gives one session a unified view across repos whose layout the tool itself does not control. Treat the two as complementary rather than a choice — the umbrella directory scopes the repos, worktrees (built-in or manual) scope the branches inside each one.

Git submodules vs manual checkouts vs monorepo migration

Git submodules nest one repository inside another at a pinned commit, which sounds like a tidy answer to "the agent can't see the dependency" — the dependency's source is now sitting inside the parent's working tree. In practice, submodules solve discoverability but not currency: the pin is frozen until someone runs git submodule update, and an agent that trusts what is on disk will confidently write code against a shared-library version your team stopped using weeks ago. If you use submodules, name the pinned commit and its age explicitly in your manifest so the agent (and the human reviewing its output) knows to check freshness before trusting it.

Manual checkouts inside an umbrella workspace, as shown above, avoid the staleness trap because each repo is on its own live branch, but they require the manifest to do the work submodules do automatically — telling the agent where things are. A full monorepo migration removes the problem at the root by making "which repos does this touch" a non-question, but it is a genuine organisational undertaking with its own costs, covered in the comparison below and in our separate guide to migrating a legacy codebase with AI coding agents if a migration is already on your roadmap for other reasons.

Every article here is written by a Verified Builder. Want your name on the next one?

AI Tech Connect lists AI engineers, founders and researchers across India and the UK — and the people hiring browse it to find them. Adding your profile is free.

Become a Verified Builder →

Monorepo, polyrepo or hybrid: which is agent-friendly?

Whether to consolidate repositories is an organisational decision with consequences well beyond agent tooling — ownership boundaries, access control, CI topology and release cadence all matter more than what makes an agent's life easiest this quarter. Still, the agent-friendliness dimension is real and worth weighing explicitly against the alternative of adding a repo map and workspace layer on top of what you already have.

Dimension Monorepo Polyrepo Hybrid (manifest + worktree workspace)
Cross-repo refactors Single atomic commit; the agent sees the full dependency graph on disk Needs coordinated PRs across repos; the agent must be told the dependencies exist Agent reads the manifest, then opens only the repos the task actually touches
Agent context cost Large tree — needs deliberate scoping (see pitfalls) or the agent reads far more than the task needs Small per-repo context, but no shared view unless something builds one Small per-repo context plus one lightweight manifest — usually the cheapest of the three
Build and CI speed Needs incremental build tooling (Nx, Turborepo, Bazel or similar) to stay fast as it grows Naturally fast per repo; cross-repo integration testing is the usual bottleneck Same profile as polyrepo — the manifest sits above the build graph, it doesn't change it
Discoverability for a fresh agent session High by default — one directory listing and one AGENTS.md hierarchy cover everything Low by default — the agent has no reason to suspect sibling repos exist High if the manifest is kept current; degrades to polyrepo-level if it goes stale
Team and ownership scaling Gets harder past a handful of independently-owned services; access control is coarse-grained Scales cleanly with per-repo ownership, permissions and release schedules Scales like polyrepo — the manifest is additive and doesn't change who owns what
Typical failure mode Context bloat — the agent reads far more of the tree than one task needs The agent "forgets" a sibling repo exists and reinvents a type or contract that already lives there The manifest goes stale and quietly misleads the agent instead of helping it
Avoid

Migrating to a monorepo primarily to fix agent confusion. It is a multi-month project with real costs, and a stale repo map will produce the same "agent forgot a dependency exists" failure inside a monorepo's less-visited corners as it does across separate repos. Fix the context problem with a manifest first; revisit repo topology only if independent reasons already justify it.

Scoping tasks and running subagents per repo

Once repos are discoverable and locally checked out, the remaining decision is how to split the actual work. The pattern that holds up well in practice is a coordinating session that reads the manifest and produces a short task plan, followed by one focused subagent or sub-session per repo, each working inside its own worktree so their edits cannot collide. This is the same discipline covered in our guide to orchestrating subagents for multi-agent patterns, applied specifically to the repo boundary rather than a feature boundary.

Scope each sub-task the way you would scope a well-written ticket: name the repo, name the specific files or modules in play, and state the contract the sub-task must honour with its neighbours (a function signature, a schema shape, an API route). This is the same instinct behind spec-driven development — an agent that knows the exact shape it must produce coordinates far better with a sibling agent it never directly talks to than one working from a vague "make it work" brief.

Worked example A — a cross-repo API contract change

Task: add a reason_code field to the refund API, flowing from the shared contract through the service to the infra config that documents the schema for downstream consumers.

1. Coordinator reads workspace.yaml, identifies 3 repos in scope:
   shared-types (owns the contract), payments-api (implements it),
   platform-infra (publishes the OpenAPI doc consumers read).

2. Coordinator writes a one-page task plan:
   - shared-types: add `reason_code: RefundReasonCode` to RefundRequest,
     bump package minor version, publish.
   - payments-api: bump @acme/shared-types dependency, thread the field
     through the handler and the billing service, add a test.
   - platform-infra: regenerate the published OpenAPI doc from the new
     shared-types version; no logic changes.

3. Three worktrees opened, one per repo, all on branch
   feat/refund-reason-code. A sub-agent (or sub-session) is scoped to
   each worktree with only its slice of the plan.

4. shared-types sub-task runs first and must finish before the other
   two start, since they depend on its published output — everything
   else can run in parallel.

5. Coordinator reviews the diff from each worktree against the
   contract stated in step 2 before opening the three PRs.

The sequencing in step 4 matters more than the parallelism: a dependency graph, not just a repo list, tells you which sub-tasks must complete before others can safely start. Running everything in parallel regardless of dependency order is the fastest way to get a payments-api sub-task guessing at a contract that shared-types hasn't finished defining yet.

Worked example B — coordinated frontend, backend and shared-types feature

Task: a fintech team — the scenario holds equally for a Bangalore product company or a London scale-up — is adding a new settlement-status field that a web frontend, a backend service and a shared-types package must all agree on.

manifest scope for this task:
  - shared-types   → source of truth for SettlementStatus enum
  - backend-api    → depends_on: shared-types
  - web-frontend   → depends_on: shared-types, backend-api (read-only, via generated client)

plan:
  1. shared-types: add new enum values, publish patch version.        [sequential, first]
  2. backend-api:  consume new version, extend status transition
                    logic, regenerate the API client web-frontend
                    imports.                                          [depends on 1]
  3. web-frontend: consume the regenerated client, add the new
                    status to the UI state machine and copy.          [depends on 2]

Here the dependency chain is strictly linear rather than fan-out, so the honest answer is that parallelism buys little — running all three sub-tasks at once just means two of them stall waiting on an artefact the first hasn't produced yet. The value of scoping this explicitly isn't speed; it's that each sub-task gets a narrow, unambiguous brief instead of an agent in web-frontend guessing at a status enum that does not exist yet anywhere it can see.

Common pitfalls in multi-repo agent workflows

Five failure patterns account for most of the friction teams report once they move from single-repo to multi-repo agent work.

  • Letting the agent discover repos by exploring instead of by manifest. Without an explicit "read this first" step, an agent will either stay inside the repo it started in and silently under-deliver, or spend several turns groping for sibling repos it was never told about. Both waste tokens and turns that a two-line manifest read would have saved.
  • A manifest or repo map that has gone stale. A workspace.yaml that still lists a repo which was archived last quarter, or omits one added last week, is worse than no manifest at all — the agent trusts it and acts confidently on wrong information. Review it in the same pull request that changes repo topology, not on a separate cadence nobody owns.
  • No single source of truth for a shared contract. When a type, schema or API shape is defined once but copy-pasted into two consuming repos "for convenience", an agent editing one copy has no way to know the other exists, and the two silently drift. Publish the contract from one repo and have the others depend on it, even if that dependency is just a versioned package.
  • Running unscoped parallel work with no merge plan. Opening three worktrees and three sub-tasks is easy; deciding who reviews what, in what order, and how conflicting edits to a shared file get reconciled is the part teams skip. Decide the merge order before you start the sub-tasks, not after they finish.
  • Treating a submodule or vendored copy as free context. Nesting a dependency's source inside your working tree makes it readable, but the agent still needs to be told what it is, how current the pin is, and that edits to it don't belong in the parent repo's pull request.

Building your team's multi-repo playbook

None of this requires new tooling to get started. A manifest is a text file. A worktree-per-repo workspace is a handful of git commands. Scoping a sub-task to a named repo and a stated contract is a habit, not a product. What changes the outcome is doing these three things deliberately and consistently, rather than leaving an agent to infer repo boundaries from whatever happens to be in its working directory when a session starts.

Start small: write the manifest for the two or three repos your team's agents touch most often, add a "read the manifest first" line to whatever standing context file you already maintain, and run one real cross-repo task through the worked-example pattern above before rolling it out further. The habit compounds the same way a good AGENTS.md file does inside a single repo — it is written once, costs a few lines of context per task, and quietly raises the floor on every cross-repo change an agent makes from then on. It also sits naturally alongside the wider discipline the industry has taken to calling context engineering: curating exactly what an agent sees, at the repo level as much as the file level.

Tooling in this space is still maturing quickly, so treat specific product capabilities as a snapshot rather than a permanent state of the art, and check primary docs for the version you actually run. For further reading: the AGENTS.md standard, Claude Code's worktree documentation, Aider's repository map docs, and our own guide on getting more from AI coding agents for workflow patterns beyond the multi-repo case.