Skip to content

Course · Copilot · Rules (custom instructions)

Path-specific rules with applyTo

A repo-wide file has one blind spot: it treats every file in the repo the same. That is fine until part of the repo deserves stricter handling than the rest. A shared library is the standing example - in this course’s illustrative scenario, shared-lib, the internal library whose validation, auth, and audit helpers a dozen services import. A sloppy change there ripples outward in a way a change to a private utility never would. You want the helpers held to a tighter standard than the repo’s tests and scripts, and “be more careful here” is exactly what a single repo-wide file cannot express.

Path-specific instructions are the tool for that - *.instructions.md files under .github/instructions/, each scoped by an applyTo glob. You write a rule that attaches only to files matching the glob, and Copilot pulls it in in addition to the repo-wide file when the files it is editing match.

Path-specific rules live as *.instructions.md files under .github/instructions/ - Copilot looks there recursively, so you can organize in subfolders. Each file carries frontmatter, and the load-bearing field is applyTo:

---
applyTo: "shared-lib/src/**/*.ts"
description: "Stricter rules for the shared helpers consumed by 12 services"
---
These files are imported by ~12 downstream services. Treat every change as
potentially breaking.
- Never change an exported function's signature or return type without flagging
it explicitly in your summary - it is a breaking change for consumers.
- Add new behavior behind new exports; prefer additive changes over edits to
existing exports.
- Every audit event goes through the existing event-type union - extend the
union, don't pass free-form strings.
- Validation rules are pure and side-effect free. Keep them that way.

The fields:

  • applyTo (required) - a glob, relative to the workspace root, deciding which files this rule attaches to. "shared-lib/src/**/*.ts" scopes it to the library’s source tree, recursively, and nothing else - not its tests, not the service next to it in the same repo (glob examples as of September 2026).
  • name and description (optional) - labels describing what the rule is for.

Copilot reads .github/instructions/ by default. The chat.instructionsFilesLocations setting can point it at additional locations and is not deprecated, but custom locations are not recommended for Copilot workflows because GitHub Copilot CLI and the GitHub Copilot app do not inherit editor settings (per the custom instructions documentation, as of October 2026). Prefer the native folders so every Copilot client sees the files.

The part to internalize: when the files Copilot is editing match your glob, the path-specific rule combines with the repo-wide file (your copilot-instructions.md, AGENTS.md, or CLAUDE.md) - it does not override it. GitHub’s repository instructions page states it directly, as of September 2026: when the path matches and a repository-wide file also exists, “the instructions from both files are used.” For a file under shared-lib/src/, Copilot holds both in context: the repo’s general conventions and the stricter helper rules. The repo-wide file says “this is how we write code here”; the path-specific file adds “and in this directory, treat every change as potentially breaking.” Layered, not either-or.

That is why the mechanism maps so cleanly onto a shared library: general conventions apply everywhere, and the high-consequence source directory gets an extra ring of rules wrapped around exactly the paths that ripple. The judgment is the same one behind matching latitude to risk - expressed in files instead of chat roles.

For a service-plus-library setup, a clean division falls out:

  • Your service repo - a repo-wide file is usually enough; your squad owns it and the stakes are even across it.
  • The shared library - a repo-wide file for general conventions, plus a path-specific file over the library’s source directory encoding the “many consumers, treat every change as breaking” discipline.

Rules can also arrive from more than one machine- and org-level source at once. When layers disagree, something has to win. How rules layer - personal, repo, organization.