Large codebases

In a big repository, the agent’s biggest enemy is noise: instructions for teams you do not work with, generated files that turn up in every search, and thousands of files competing for a limited context window. This guide shows how to set up a monorepo so each session sees what matters for the work at hand and little else.

The example

The settings below use a monorepo like this:

acme/
├── SYNTIC.md                  # repo-wide rules
├── .syntic/
│   ├── settings.json
│   └── rules/
├── services/
│   ├── billing/   (Go)
│   ├── search/    (Rust)
│   └── web-api/   (TypeScript)
├── apps/
│   ├── web/       (React)
│   └── admin/     (React)
├── libs/shared/
├── vendor/
└── gen/                       # generated protobuf code
Setting or fileUsed for
SYNTIC.md per folderInstructions that load only where they apply.
.syntic/rules/ with paths:Rules for file types or areas across the tree.
synticMdExcludesInstruction files to skip.
permissions.deny with Read(...)Keeping generated and vendored code out of reach.
respectGitignore (on by default)Keeping ignored files out of @ suggestions.
worktree.sparsePathsChecking out only some folders in worktrees.
--add-dir, permissions.additionalDirectoriesReaching folders outside the one you started in.
Skills in subfoldersProcedures for one area.

Start in the right folder

Start syntic in the folder you are working on, not always at the repository root:

cd acme/services/billing
syntic

The agent works in that folder and below. Instruction files from the folders above it (up to the repository root) still load, so repo-wide rules apply. Start at the root only for work that really spans the tree, such as a cross-cutting refactor.

Layer instructions by folder

Keep the root SYNTIC.md short and about the whole repository: how to build, the shared conventions, where things live. Put area-specific detail next to the code:

acme/SYNTIC.md                      # build system, shared conventions
acme/services/billing/SYNTIC.md     # money is integer cents, run `make test`
acme/apps/web/SYNTIC.md             # component patterns, `pnpm test`

A SYNTIC.md in a subfolder loads when the agent starts working there. More specific files load later, so they win when instructions conflict. See Memory.

Folder files or path-scoped rules?

UseWhen
SYNTIC.md in a folderThe guidance is about one area of the tree and its owners maintain it.
.syntic/rules/<topic>.md with paths:The guidance follows a file type or pattern across many folders.
---
paths: "**/*.proto"
---
After editing a .proto file, run `make gen` from the repository root.
Never edit files under gen/ by hand.

Skip instruction files you do not need

Vendored code and other teams’ areas may carry their own SYNTIC.md or AGENTS.md. Leave them out:

{ "synticMdExcludes": ["vendor/**/SYNTIC.md", "vendor/**/AGENTS.md", "services/legacy/**"] }

A pattern without / matches a file name; one with / matches the end of the path. Check what loaded with /memory.

Keep the agent out of noise

Block generated and vendored code

Searches that land in generated code waste context and tempt the agent to edit files that will be overwritten. Deny reading them:

{
  "permissions": {
    "deny": ["Read(gen/**)", "Read(vendor/**)", "Read(**/node_modules/**)", "Edit(gen/**)"]
  }
}

Put this in .syntic/settings.json so the whole team gets it. See Permission rules.

Keep @ suggestions focused

Git-ignored files are left out of the @ file picker by default (the respectGitignore setting). Keep it on in a large tree: build output and dependencies would otherwise flood the suggestions.

Text search finds every string match, including comments and generated copies. A language server answers “where is this defined” and “who calls this” precisely, with far fewer file reads. Install a code intelligence plugin for the languages you use (Code intelligence).

Let subagents do the searching

“Use the explore agent to find every caller of ChargeCard across services” keeps the search results out of your main conversation. Only the summary comes back. See Subagents.

Scope worktrees and folders

Check out only what you need

Parallel sessions in worktrees normally get a full checkout. In a very large repository, limit them:

{
  "worktree": {
    "sparsePaths": ["services/billing", "libs/shared"]
  }
}

This applies to syntic -w, worktrees the agent creates, isolated agents and background runs.

Reach across folders

Working in services/billing but need to read libs/shared? Add it for the session:

syntic --add-dir ../../libs/shared

Or inside a session, /add-dir ../../libs/shared. Add --remember to /add-dir to save it in permissions.additionalDirectories for next time. Added folders are also offered to MCP servers that ask which folders they may use.

Give each area its own skills

A skill in a subfolder’s .syntic/skills/ is available when you work there:

services/billing/.syntic/skills/add-migration/SKILL.md
apps/web/.syntic/skills/new-component/SKILL.md
---
name: add-migration
description: Create and test a billing database migration
---
1. Create the file with `make migration name=<name>`.
2. Write the up and down steps. Never lock the invoices table.
3. Run `make test-migrations` and fix anything that fails.

Give each skill a clear description so the agent knows when to use it. /skill-doctor shows which skills cost context and which went unused (Skills).

When layering stops scaling

Past a few dozen teams, per-folder files get hard to keep consistent. At that point:

  • Package shared conventions, skills, agents and hooks as a plugin and install it across repositories.
  • Use managed settings for rules every repository must follow.
  • Keep the root SYNTIC.md to a short map of where things live, and let folder files carry the detail.

Plan changes that span packages

For a change that touches many packages:

  1. Map it first. In plan mode, ask: “List every package that imports libs/shared/money and what each uses from it.” Save the answer to a file.
  2. Split it. Ask for an order of steps where each leaves the build green.
  3. Fan out. /batch <task> gives each part its own agent and worktree; a workflow runs many similar steps in parallel and merges the results.
  4. Review together. /code-review high on the combined branch before merging (Code review).

Put it together

A .syntic/settings.json for the example monorepo:

{
  "synticMdExcludes": ["vendor/**/SYNTIC.md", "vendor/**/AGENTS.md"],
  "permissions": {
    "deny": ["Read(gen/**)", "Read(vendor/**)", "Edit(gen/**)"],
    "allow": ["Bash(make test:*)", "Bash(pnpm test:*)"]
  },
  "worktree": {
    "baseRef": "fresh",
    "sparsePaths": ["services", "libs/shared"]
  }
}

For very large codebases, a model with a long context window may be offered on your plan. /model shows each model’s window. See Models.