Repository instructions bootstrap for GitHub Copilot
A starter layout for .github/copilot-instructions.md, path-specific instruction files, and AGENTS.md so Copilot stops guessing how your repo works.
#agents #coding
What vetted this — trust report
What this is for
GitHub Copilot performs better when the repository tells it how to build, test, review, and navigate the codebase. This template gives you the three instruction layers Copilot consumes, and — more usefully — a rule for deciding which layer a given rule belongs in.
The layering matters because instructions compete for attention. A file that carries every rule for every language means your SQL conventions are in context while it edits a React component, and the relevant rules get diluted by the irrelevant ones.
Layer 1: repository-wide instructions
Create .github/copilot-instructions.md. Use it for rules that apply everywhere: how to build
and test, the quality bar before finishing, which commands are safe or preferred.
# Copilot instructions
## Product and architecture
- What the repo does, in two sentences.
- The key projects and where major features live.
- Which layer may depend on which. Anything that must not depend on anything.
## Commands
- Build: ...
- Targeted tests: ...
- Full tests: ...
- Run locally: ...
- Known failure: <the command that fails confusingly, and why>
## Working rules
- Prefer small, local edits.
- Read the nearest implementation and its tests first.
- Run the narrowest validation command after the first real edit.
- Ship a migration with any model change.
## Code review
- Report only findings with a concrete failure mode.
- Do not report style the linter enforces, or "consider extracting" with no stated problem.
- Always report anything the diff removed or weakened.
## Output expectations
- Mention changed files.
- Mention validation performed.
- Separate open assumptions from verified facts.
Keep it to about a page. It's read on every request.
Layer 2: path-specific instructions
Create files under .github/instructions/*.instructions.md when rules differ by area. The applyTo
frontmatter glob is what scopes them.
---
applyTo: "src/**/*.cs,tests/**/*.cs"
---
Use the existing dependency-injection patterns; don't introduce a service locator.
Prefer the xUnit style used in the nearest test file.
Nullable reference types are enabled — don't suppress warnings, fix them.
---
applyTo: "**/*.tsx"
---
Function components only. No class components.
Data fetching goes through the query hooks in `src/api/`, never useEffect + fetch.
Use this layer for language-specific conventions, folder-specific architecture rules, and test patterns that differ by slice. This is the most underused of the three and usually the one that improves output most, because it's the only layer that can be specific without being noisy.
Layer 3: agent instructions
Create AGENTS.md near the code that needs local operating rules. Agents read the nearest file in
the tree, so a package-level file overrides a root one — which is what makes this the right layer
for a monorepo where each package has its own build and its own traps.
Use it for the best validation sequence for that subtree, generated files not to edit directly, and expensive or flaky commands.
AGENTS.md is also the cross-vendor file: Codex, Cursor, Gemini CLI, Aider, Zed and others read it
too. If you're going to write one file properly, this is a good candidate.
Rule of thumb
| File | Scope | Answers |
|---|---|---|
.github/copilot-instructions.md |
Whole repo | How does this project work? |
.github/instructions/*.instructions.md |
Path glob | How do we write code here? |
AGENTS.md |
Nearest directory | How should an agent operate in this subtree? |
When a rule could live in two layers, put it in the narrower one. Narrow rules are more specific, and specificity is the thing that changes behaviour.
What actually changes behaviour
The single test for any line: would an agent that ignored this sentence write code that compiles, passes tests, and is still wrong?
Passes the test:
- "Never restate a visibility rule in a query —
PublicOnly()owns that predicate." - "A model change must ship with a migration; they auto-apply on startup."
- "
dotnet testfails with MSB3021 while the debugger is attached — build to a separate output dir."
Fails the test (delete these):
- "Write clean, maintainable code."
- "Follow best practices."
- "Use meaningful variable names." (the linter, or nobody)
- Anything restating framework documentation.
Rollout
- Start with
copilot-instructions.mdand five real rules. Not thirty. - Work for a week. Every time you correct Copilot twice for the same thing, add a line.
- When a rule only applies to one language or folder, move it down to layer 2.
- When a rule becomes enforced by a test or a linter, delete it — something better now owns it.
- Review the files in PRs like any other code. A stale command in here costs someone an afternoon.
Failure modes
- The file is long and nothing improved. Too much aspiration, not enough specificity. Delete every line that fails the test above; what's left is the file you actually wanted.
- Rules contradict the codebase. The agent gets conflicting evidence and picks unpredictably. A rule you don't enforce is worse than no rule.
- Everything is in layer 1. Front-end rules are competing with back-end rules on every request. Split them by glob.
- Instructions ignored on large diffs. Compliance degrades as context fills. Smaller PRs, which you wanted anyway.
- Nobody updates it. Assign it an owner, or accept that it will describe the repository as it was a year ago.
Why it works
Copilot can only follow repo-specific rules that exist somewhere concrete. These three files turn tribal knowledge — the things your team knows and never wrote down — into defaults the agent uses on every request, and, not incidentally, into onboarding documentation for the next human hire.
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.