DEV Community

Bogdan
Bogdan

Posted on

Why coding agents get lost in a monorepo — and the one file that fixes it

You know the scene. You drop Claude Code (or Copilot, OpenCode, Gemini…) into a
repo with forty projects. It greps its way into a module. Twenty minutes later
it's still guessing: "does this module own the contract, or consume it? who
else breaks if I change that interface? where do I actually add this feature?"

The agent isn't stupid. It found the files. The files just don't tell it the
context.

"What is where" is not "who depends on whom"

Most repos have a REPOSITORY_MAP.md. That's "what is where": entry points,
key paths, where to edit. Valuable. But it answers one question.

Enter a real module and you need a different map:

  • What does this module own, and what does it explicitly not own?
  • Which contracts/events do other modules rely on?
  • Who depends on it — i.e., what breaks when I rename a public type?
  • What's the invariant that took two weeks to learn last time?

A flat index can't carry that without turning into a second documentation site
nobody maintains.

A concrete, illustrative example. Say a payments monorepo has a
CheckoutModule:

  • its package.json (or .csproj, Cargo.toml…) lists 3 direct deps
  • but 6 other modules depend on it

The manifest shows 3. The blast radius is 6. An agent that reads the manifest
and thinks "small, safe change" will happily break five neighbors.

The fix: one file per module, written by the agent

Instead of a generated dependency graph (machines are great at edges but
useless at "why"), use agent-written context files:

<module>/CONTEXT.md
Enter fullscreen mode Exit fullscreen mode

And make the repo map point at them:

## Modules & Context
| Module        | Role               | Context                                     |
|---------------|--------------------|---------------------------------------------|
| `src/checkout`| payments domain    | `src/checkout/CONTEXT.md`                    |
| `ui/billing`  | customer dashboard | `ui/billing/CONTEXT.md`                      |
| `gateway`     | API edge           | (no context — run /spk-module-context gateway) |
Enter fullscreen mode Exit fullscreen mode

Now the handoff is explicit: the map says what exists, the CONTEXT.md says
what it is. An agent entering src/checkout reads one file instead of
re-deriving the architecture by grepping the whole tree.

Keep CONTEXT.md short (~60 lines):

## Purpose

Owns the checkout + payment orchestration flow.

## Responsibilities

- Create and cancel orders
- Run payment providers (stripe, paypal) behind a port
- NOT: pricing, inventory — those come from other modules

## How it works

- `OrderService` is the entrypoint; `PaymentGateway` is the port
- Events: `OrderPlaced`, `PaymentFailed` on the shared bus
- Config keys: `checkout.timeout_ms`, `checkout.providers`

## Public contracts

- `IOrderService`, `CheckoutStatus` enum — stable, do not break
- Consumed by: `gateway`, `ui/billing`, `reports`

## Gotchas

- Idempotency key on create; refunds are async and must be retried
- Never call `Inventory` directly — go through the event
Enter fullscreen mode Exit fullscreen mode

How it works in practice

In speckeep (v1.1.1+) it's two commands:

/spk-repo-map                       # maintain the map + ## Modules & Context
/spk-module-context src/checkout    # agent writes/refreshes src/checkout/CONTEXT.md
Enter fullscreen mode Exit fullscreen mode

/spk-module-context <path> is a skill: the agent reads the folder, checks the
repo map, and writes the prose. You run it when onboarding into a module or
after a refactor. The implement prompt even suggests it when a change
creates or restructures a module, so the docs stay fresh without process.

Try it without installing anything:

npx speckeep init my-repo --agents claude
# in your agent: /spk-module-context src
Enter fullscreen mode Exit fullscreen mode

(Requires a skill-capable agent — Claude Code, OpenCode, Gemini, … — and
speckeep v1.1.0+, when a module is documented.)

When this is not the answer

  • Tiny repos with one module — one more file is noise.
  • You need machine-computed facts (cycle detection, impact sets for CI). Then a generated graph is the right tool; treat CONTEXT.md as the human/agent layer on top.
  • You want zero agent involvement — write CONTEXT.md by hand, but plan to refresh it, or it rots like every doc.

The one-line takeaway

Agents don't lose context because they can't find files. They lose it because
the files don't answer "what is this, who depends on it, what may I touch".
Point REPOSITORY_MAP.md at per-module CONTEXT.md, let the agent write
them, and the next session starts from understanding instead of archaeology.

Top comments (0)