How do I make an AI agent use the right rules for each part of a monorepo?

Mira and Noor compare work across two laptops while Noor marks an open notebook at their desks.

TL;DR

In a monorepo, an agent follows a package's conventions only if that package's rules are in context when it edits the package's files, and Claude Code, Codex and Cursor each load them at different moments. Keep repo-wide rules at the root, put each package's conventions in a file scoped to it, start the agent where your tool expects, and write down which rule wins when a change crosses packages. A reviewer can then check, file by file, which rules applied.

Loading and precedence in a monorepo

In January 2026 a developer on the Cursor forum described moving their company into a monorepo with a Laravel API, a Nuxt admin dashboard built on Bootstrap and a Nuxt public store built on Tailwind. A root rule told the agent to respect the rules in each sub-directory, and the admin app had its own rule file. The agent still wrote custom CSS instead of Bootstrap classes in the admin app. They asked whether Cursor supports nested .cursor folders or whether everything should move to the root with specific globs.

Months earlier, someone opened an issue on the AGENTS.md project itself asking which file takes precedence when a large monorepo has several AGENTS.md files with conflicting instructions. The issue was still open, with no maintainer answer, when this article was checked.

The first is a loading problem: did the package's rules reach the agent at all? The second is a precedence problem: when two rule files both apply, which should win?

Each tool decides differently when a package's rules load

The documentation for each tool, checked on 30 September 2026, describes different triggers:

ToolRoot and parent filesA package's own filesHow they combineScoped option
Claude CodeLoaded at launchLoaded when Claude reads files in that directoryConcatenated, root first.claude/rules/ with paths:; claudeMdExcludes to skip other teams' files
CodexRoot down to the start directory, one file per directoryNot read if the package is below the start directoryConcatenated, nearer files laterAGENTS.override.md in a directory
CursorProject rules and root AGENTS.mdNested AGENTS.md applied when working with files in that directoryCombined, more specific wins.mdc rules with globs
Gemini CLIWorkspace and parent directoriesPicked up when a tool accesses a file there; its configuration reference also describes a capped scan below the start directoryConcatenatedAlternative file names only

Sources: Claude Code memory documentation and its monorepo page, the Codex AGENTS.md guide, Cursor rules documentation and Gemini CLI context files.

Three details matter most in practice.

Codex does not look below where you start it. Its guide says discovery walks from the project root to the current directory and stops there. If you start Codex at the repository root and ask it to change apps/api, the API's own AGENTS.md is not in the chain. Start it in the package (codex --cd apps/api), or make sure the root file names each package's conventions.

Claude Code loads package files lazily, and the trigger may be narrower than the docs imply. The documentation says subdirectory CLAUDE.md files are included when Claude reads files in those subdirectories. An open bug report from August 2026 tested 27 ways of touching a file on Windows and found that only the Read tool loaded them. With no maintainer response yet, treat it as something to test in your own setup.

Cursor's current page no longer documents nested .cursor/rules folders. A staff reply in the forum thread above says they are supported, and an archived 2025 version of the docs described them, but the September 2026 page documents glob-scoped root rules and nested AGENTS.md files instead. Use those for a setup you can defend from the documentation.

The AGENTS.md site says the closest file to the edited file wins. The tools mostly concatenate files with the nearer file read later, which is not quite the same thing: a root instruction that the package file does not contradict still applies.

Illustration seen from above of Mira and Ivo at a meeting table, each pressing a finger to a line in a different printed instruction document and looking up at each other in amused disagreement.
When a root rule and a package rule both reach the agent, which one wins is a decision to write down, not a guess.

Write the rules so each package boundary is explicit

  • Root file: what is true everywhere. Commit and branch conventions, how the packages relate, which package owns what, where each package's rules live, and the precedence rule for conflicts. Nothing stack-specific.
  • Package file: that package's stack. Laravel conventions in apps/api, Bootstrap usage in apps/backend, Tailwind usage in apps/frontend, import boundaries in packages/ui. Each file names its package in its first line, so it is unambiguous when several are loaded together.
  • No delegation in prose. The root rule in the Cursor thread told the agent to respect the rules in each sub-directory. That only works if the agent has loaded those files, which is the part that failed. A glob-scoped rule or a nested file that loads with the package's files does not depend on the agent choosing to look.

If your team uses several tools, nested AGENTS.md files cover Codex, Cursor and Copilot, and Claude Code reads them directly or through imports. Maintaining one set of project instructions across AI coding tools shows how to keep the tools' files from drifting apart.

When one change crosses packages

A feature that adds an API endpoint, a store page and a shared button touches three rule sets at once. The admin app's "Bootstrap classes only" and the store's "Tailwind utilities only" are both correct, for different files. Write a precedence rule into the root file and make it about files, not about the task:

  1. For any file, the rules of the package that owns the file apply.
  2. Inside a shared package, the shared package's rules win over any app's rules.
  3. Root rules apply everywhere unless a package rule explicitly narrows them.

Then treat a cross-package feature as a sequence of per-package changes, each reviewed by someone who knows that package's conventions, with the shared package changed first when others depend on it.

Paqad selects rules by changed file path, deterministically, which makes the cross-package case concrete. Its trigger matcher at commit 29548baf was run against a fixture of five rules, one always loaded and four scoped to apps/api/**, apps/backend/**, apps/frontend/** and packages/ui/**.

That over-match is harmless here, and the recorded matched path explains it. A path matcher can also miss a rule a change needs, so test both directions on your own tree.

Illustration of Noor at a monitor turning to ask Mira, who stands beside it with her arms folded, while Ivo waits behind Noor's chair with a notebook.
A change that crosses packages brings several rule sets into one review; check each file against the package that owns it.

Check which rules applied to each changed file

A diff alone does not show whether the right rules were in play. Each tool gives you some way to check:

  • Claude Code: run /context and look under Memory files, as the monorepo page recommends. For lazy-loaded package files, an InstructionsLoaded hook can log which file loaded, when and why.
  • Codex: confirm which directory the session started in, then audit the loaded files with -c log_dir=./.codex-log and the resulting log.
  • Cursor: for an unapplied rule, check the rule type and that the glob matches the referenced files.
  • Gemini CLI: /memory show displays the full concatenated context.

In review, name the owning package and the rule file that should have applied for each changed file, and compare that with what loaded. Paqad records this per change: rules-loaded.json lists every applicable rule with the changed paths that matched it, and on its wired Claude Code and Codex paths a covered source edit is refused until that record exists. The record shows which rules were loaded for which files, not that the agent applied them correctly. To get that record for your own cross-package changes, install Paqad; its documentation explains how it selects rules from the files a change touches.

If the rules loaded and were still not followed, the cause is compliance rather than selection, and the article on why a coding agent keeps ignoring the project rules shows how to tell the two apart.

Frequently Asked Questions

Scope each package's conventions to that package and make loading independent of the agent's choices: a nested file or path-scoped rule loads with the package's files, while a root sentence asking the agent to "respect sub-directory rules" depends on it going to look.

Use the tool's own listing, not the agent's recollection. For files that load on demand, the most useful record is a log written at load time, such as Claude Code's InstructionsLoaded hook, because a /context check made later shows the session's state then, not at the moment of the edit.

By file ownership, written at the root. Test the rule with a real conflict: give one package "Bootstrap classes only" and another "Tailwind only", change a file in each, and confirm each diff follows its own package. If one does not, the precedence text is too vague or one file never loaded.

Several rule sets apply at once, each to different files, and one long session tends to blur them. Splitting the work also gives each owner a diff limited to their package. With Codex, run each step from the package directory so its instruction file is in the chain.

Compare the expected rule per file with the recorded selection. A match shows the right rules were in context; it does not prove they were followed, so the diff still needs review against the package's conventions and, where possible, a mechanical check in CI.