Concepts

Every file type on this page is an abstraction layer in a reliability stack. The stack defines where each asset lives in the agent’s context and how much it costs to load — not all context is equal, and not all assets load on every request.

The 5-Layer Reliability Stack

┌─────────────────────────────────────────────────────────────┐
│  LAYER 5 — EVALUATOR / VERIFICATION                         │
│  verify-app subagent, tests, hooks, PostToolUse             │
├─────────────────────────────────────────────────────────────┤
│  LAYER 4 — SUBAGENTS / AGENT TEAMS                          │
│  Isolated workers for context-safe parallel execution       │
├─────────────────────────────────────────────────────────────┤
│  LAYER 3 — SKILLS / SLASH COMMANDS                          │
│  Repeatable workflows, domain knowledge, inner-loop tasks   │
├─────────────────────────────────────────────────────────────┤
│  LAYER 2 — PLANNING (Plan Mode / Plan Agent)                │
│  Spec → PRD → Architecture → Task List before any code      │
├─────────────────────────────────────────────────────────────┤
│  LAYER 1 — MEMORY / CONTEXT                                 │
│  copilot-instructions.md / CLAUDE.md — always-on context   │
└─────────────────────────────────────────────────────────────┘

Each section below maps to a layer. The order here — from Memory up to Evaluator — is the order you build in. Set Layer 1 before you write a single prompt.


Custom Instructions

Layer: Memory (Layer 1)
Lives at: .github/copilot-instructions.md (repo-wide) or *.instructions.md files (scoped)
What it is: Always-on context loaded before every request in the workspace.
When to use it: Project coding standards, toolchain rules, naming conventions, anti-patterns — anything the agent must always remember.

The hierarchy: .github/copilot-instructions.md applies to every request. An *.instructions.md file in a subfolder can scope rules to specific file patterns via the applyTo frontmatter. Both are cross-compatible — VS Code Copilot, Claude Code, Cursor, and Gemini CLI all discover these files.

The 70% rule (Boris Cherny): instructions compliance is approximately 70%. For non-negotiable rules — never commit to main, never write to prod — move them to Hooks instead. Instructions are for conventions; hooks are for enforcement.

Keep instructions under 50–100 lines. Long instructions are ignored instructions. Ask “would removing this cause the agent to make a mistake?” If not, cut it.

---
applyTo: "**/*.ts,**/*.tsx"
---
- Use strict TypeScript — no `any`
- Prefer `type` over `interface` for object shapes
- Use Zod for all runtime validation
- Never use `console.log` — use `logger.debug()`
- Imports: external packages first, then internal, alphabetical within each group

Official docs: Custom instructions in VS Code
Reference: §1.1 Memory Layer — CLAUDE.md


Prompt Files

Layer: Skills (Layer 3)
Lives at: .github/prompts/*.prompt.md
What it is: Named, reusable prompts invoked via /prompt-name in chat.
When to use it: Repeatable workflows you’d otherwise retype — “generate unit tests”, “prepare PR description”, “audit this for security issues”.

Unlike instructions (always-on), prompt files are on-demand. They also accept frontmatter that locks in the model, available tools, and mode for that specific workflow. A prompt file is the first rung of the reusability ladder: it costs nothing to write and immediately makes any repeatable workflow reproducible.

The /create-prompt command in VS Code chat auto-generates a prompt file from your description.

---
name: write-tests
description: Generate comprehensive unit tests for a function or module
tools: ['codebase']
---
Read the project's test conventions from any .instructions.md files.

Analyze the function signature and behavior. Generate tests covering:
- Happy path with representative inputs
- Edge cases (empty, null, boundary values)
- Error conditions and exception handling

Use the project's test framework and naming conventions throughout.

Official docs: Prompt files in VS Code
Reference: §1.3 Skills Layer — Slash Commands


Slash Commands

Layer: Skills (Layer 3)
Lives at: Derived automatically from .prompt.md filenames — no separate file
What it is: /prompt-name invocations that run a saved prompt file by name.
When to use it: Inner-loop tasks you trigger multiple times per day.

There are no separate “slash command files” in VS Code Copilot — every .prompt.md in .github/prompts/ becomes a /command automatically. Type / in chat to see available ones alongside the built-in commands (/fix, /explain, /tests).

Boris Cherny’s core commands that earn their place:

The rule: build a slash command only for tasks you run three or more times per week. Anything less frequent is just a saved prompt in your notes — don’t create the asset.

Reference: §1.3 Skills Layer — Slash Commands


Chat Modes

Layer: Skills (Layer 3)
Lives at: .github/chatmodes/*.chatmode.md
What it is: Named chat configurations that restrict available tools and set a persistent system prompt for a type of work.
When to use it: When you need a “read-only research mode”, a “documentation mode”, or any context where a restricted toolset is correct for the whole session.

Chat modes differ from custom agents in scope: a mode applies to the entire chat interface for the session, while an agent applies to a specific task. Use modes when you want to constrain your own behavior, not delegate to another persona.

---
description: Read-only codebase exploration — no file edits allowed
tools: ['codebase']
---
You are in research mode. Explore and analyze the codebase only.
Do not write, edit, or delete any files under any circumstances.
Produce a structured summary: what exists, how it connects, what's missing.

Skills

Layer: Skills (Layer 3)
Lives at: .github/skills/<name>/SKILL.md plus supporting scripts and templates
What it is: A self-contained capability package that loads progressively — instructions first, then supporting files on demand.
When to use it: Multi-step workflows that need scripts, templates, or external resources — anything too complex for a prompt file alone.

Skills use three-level progressive loading: (1) discovery — the description field is read cheaply to assess relevance; (2) full instructions — SKILL.md loads when the skill is invoked; (3) supporting resources — scripts, templates, data load as needed. The model sees level 1 for all skills on every request; levels 2–3 only when relevant. This keeps context lean.

The SKILL.md format is cross-compatible: skills written for VS Code Copilot work identically in Claude Code, Cursor, and Gemini CLI. Use /create-skill in VS Code chat to auto-generate from a description.

---
name: api-development
description: Implement REST/tRPC API endpoints following team conventions.
  Use when creating new endpoints, handlers, or API routes.
user-invocable: true
argument-hint: "[endpoint name] [HTTP method]"
---

## API Conventions
- All endpoints validate input with Zod schemas
- Structured error responses: { error: string, code: string }
- Every handler needs try/catch with logger.error()
- Rate limiting on all public endpoints

## Steps
1. Create Zod schema in src/schemas/
2. Create handler in src/handlers/
3. Register route in src/router.ts
4. Write unit test in src/handlers/__tests__/
5. Update API docs in docs/api.md

Official docs: Agent skills in VS Code
Reference: §1.3 Skills / §2.3 VS Code Skills


Custom Agents

Layer: Subagents (Layer 4)
Lives at: .github/agents/*.agent.md
What it is: A named AI persona with a specific toolset, model, and instructions — selectable from the chat mode dropdown.
When to use it: When a task requires a distinct role with restricted tools: “CodeReviewer” with read-only access, “SecurityAuditor” with a specific checklist, “SprintFacilitator” that can never write code.

The tools field is not a suggestion — it is hard enforcement. An agent with tools: ['codebase', 'search'] cannot write files regardless of what it is instructed to do. The handoffs field lets one agent hand off to another with a pre-composed prompt, enabling explicit pipelines: Planner → Implementer → Reviewer.

---
name: Security Reviewer
description: Reviews code for vulnerabilities before deployment.
  Use when auditing PRs, new API endpoints, or auth flows.
tools: ['codebase', 'search']
model: claude-opus-4-7
handoffs:
  - label: Fix Issues
    agent: agent
    prompt: Fix the security issues identified in the review.
---

You are a senior security engineer. Read code only — never write or edit.
Review for: SQL/XSS/command injection, auth flaws, secrets in code, insecure deps.
Return: PASS / WARN / FAIL with specific file and line references.

Official docs: Custom agents in VS Code
Reference: §2.4 Custom Agents


Subagents

Layer: Subagents (Layer 4)
Lives at: Same as custom agents — .github/agents/*.agent.md with user-invocable: false
What it is: An agent that runs in an isolated context window and returns its summary to the parent.
When to use it: Any task where context isolation matters — codebase research, security review, code critique, verification, parallelizable work.

The critical concept is context isolation: the subagent starts fresh with zero memory of the parent’s session. This prevents context rot — the gradual degradation in output quality as a single session accumulates noise. The practical rule: “A fresh session starts at ~20k tokens. Quality degrades at 20–40% context fill. Do not let context exceed 60%.” Use subagents to do the work that would otherwise fill the parent’s context.

sequenceDiagram
    participant P as Parent Agent<br/>(main context)
    participant S as Subagent<br/>(isolated context)

    P->>S: delegate task<br/>(fresh context window)
    Note over S: Researches, writes,<br/>or reviews — no<br/>access to parent history
    S-->>P: returns summary<br/>(not full transcript)
    Note over P: Context stays clean.<br/>Only the summary<br/>enters the parent.

The subagent starts cold. Only its summary returns to the parent — protecting the parent's context budget.

Core subagents worth building for every project:

Subagent Tools Purpose
explore Read, search Codebase research — never use main session for this
code-simplifier Read, edit Post-implementation cleanup pass
verify-app Browser, bash E2E testing, UI verification
security-reviewer Read, search Pre-deploy security audit
test-writer Read, edit, bash Generate + run tests
---
name: security-reviewer
description: Reviews code for security vulnerabilities before deployment.
  Use when reviewing PRs, before shipping endpoints, auditing auth flows.
tools: ['codebase', 'search']
model: claude-opus-4-7
user-invocable: false
---

You are a senior security engineer. Read only — do not edit files.
Review for: SQL/XSS/command injection, auth flaws, secrets in code.
Return: PASS / WARN / FAIL with specific line references and remediation steps.

Official docs: Subagents in VS Code
Reference: §1.4 Subagents Layer


Hooks

Layer: Evaluator (Layer 5)
Lives at: .github/hooks/*.json or the hooks field in .agent.md frontmatter
What it is: Shell commands triggered deterministically at agent lifecycle events.
When to use it: Code formatting, linting, blocking unsafe operations, logging, notifications. Any side effect that must happen 100% of the time.

The enforcement gap: instructions compliance is ~70%. Hooks are 100%. Move non-negotiable rules — “always format after editing”, “never push to main”, “run tests before commit” — to hooks rather than instructions. The agent cannot bypass a hook.

Eight lifecycle events:

stateDiagram-v2
    direction LR
    [*] --> SessionStart
    SessionStart --> UserPromptSubmit : user sends prompt
    UserPromptSubmit --> PreToolUse : agent calls a tool
    PreToolUse --> PostToolUse : tool executes
    PostToolUse --> PreToolUse : next tool call
    PostToolUse --> Stop : agent finishes
    Stop --> [*]
    PreToolUse --> SubagentStart : delegates task
    SubagentStart --> SubagentStop : subagent completes
    SubagentStop --> PostToolUse
    UserPromptSubmit --> PreCompact : context near limit
    PreCompact --> UserPromptSubmit

8 lifecycle hook points. PreToolUse can block an action before it happens. PostToolUse can repair or validate after.

{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Edit|Write",
      "hooks": [{
        "type": "command",
        "command": "prettier --write \"$CLAUDE_TOOL_INPUT_PATH\" 2>/dev/null || true"
      }]
    }]
  }
}

Common hook patterns:

Official docs: Hooks in VS Code
Reference: §1.8 Hooks / §2.6 VS Code Hooks


MCP Servers

Layer: Evaluator / cross-cutting
Lives at: .vscode/mcp.json (workspace) or user MCP config
What it is: External tool connections — databases, APIs, services — exposed as callable tools in agent mode only.
When to use it: When the agent needs to query real data: a database, GitHub API, Figma designs, Slack threads, or any external system.

The 20k rule: “If you’re using more than 20k tokens of MCPs, you’re crippling Claude.” Every connected MCP server’s tool schema consumes context on every request. Load only what the current session actively uses — remove idle connections.

{
  "servers": {
    "postgres": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-postgres"],
      "env": {
        "POSTGRES_CONNECTION_STRING": "${env:PG_CONN}"
      }
    },
    "github": {
      "type": "http",
      "url": "https://api.githubcopilot.com/mcp/"
    }
  }
}

Essential MCPs by use case:

MCP Use case
Playwright Browser E2E testing, UI verification
PostgreSQL / SQLite Direct schema queries, data inspection
GitHub Issues, PRs, CI status without leaving the editor
Figma Read design specs and component properties
DuckDB In-process SQL over CSV/Parquet files
Slack Read bug reports and thread context

Official docs: MCP servers in VS Code
Reference: §1.9 MCP Servers


How It Fits Together

The diagram below shows the runtime relationships between all nine file types.

flowchart LR
    CI[".github/copilot-instructions.md\n(always loaded)"]
    INS["*.instructions.md\n(scoped by applyTo)"]
    PM[".github/prompts/*.prompt.md\n(on demand — /name)"]
    SK[".github/skills/name/SKILL.md\n(progressive load)"]
    AG[".github/agents/*.agent.md\n(selected in chat)"]
    SUB["Subagent\nuser-invocable: false"]
    HK[".github/hooks/*.json\n(lifecycle events)"]
    MCP[".vscode/mcp.json\n(external tools)"]

    CI -->|"loads before\nevery prompt"| AG
    INS -->|"scoped rules\nmerge into context"| AG
    PM -->|"invoked via /name"| AG
    SK -->|"loaded when\nrelevant"| AG
    AG -->|"delegates to"| SUB
    HK -->|"intercepts\ntool calls"| AG
    MCP -->|"exposes tools\nto agent"| AG

All roads lead to the agent. Instructions load automatically; prompts and skills load on demand; hooks intercept tool calls deterministically; MCP servers extend what the agent can reach.


VS Code ↔ Claude Code Parity

Both tools share a mental model. File locations differ; the concepts are functionally identical.

graph LR
    subgraph Shared["Shared / Cross-Compatible"]
        A["CLAUDE.md / AGENTS.md\n≡ copilot-instructions.md"]
        B["SKILL.md\n(identical format)"]
        C["*.instructions.md\n(identical applyTo support)"]
    end
    subgraph VSC["VS Code Copilot"]
        D[".github/agents/"]
        E[".github/prompts/"]
        F[".vscode/mcp.json"]
    end
    subgraph CC["Claude Code"]
        G[".claude/agents/"]
        H[".claude/commands/"]
        I[".claude/settings.json hooks"]
    end
Concept VS Code Copilot Claude Code Notes
Always-on instructions .github/copilot-instructions.md CLAUDE.md Same concept, different filename
Scoped instructions *.instructions.md (applyTo) *.instructions.md (applyTo) Identical format
Repeatable prompts .github/prompts/*.prompt.md .claude/commands/*.md Similar; VS Code has richer frontmatter
Skills .github/skills/*/SKILL.md .claude/skills/*/SKILL.md Identical SKILL.md format
Custom agents .github/agents/*.agent.md .claude/agents/*.md Similar; VS Code adds handoffs
Subagents user-invocable: false Agent() tool call Same isolation model
Hooks .github/hooks/*.json .claude/settings.json hooks Same 8 lifecycle events
MCP .vscode/mcp.json .claude/mcp.json Same MCP protocol

Skills written in SKILL.md format are compatible across VS Code Copilot, Claude Code, Cursor, and Gemini CLI. Build once, use everywhere.


Model Selection

The right model for the right task is not optional at scale — routing incorrectly costs either quality or money.

Task Recommended Model Why
Planning, architecture Opus (with thinking) Deep reasoning, fewer steering corrections
Feature implementation Sonnet Good balance of speed and quality
Code search, file exploration Haiku Fast, cheap, read-only tasks
Security review Opus High-stakes, needs careful reasoning
Boilerplate generation Sonnet Speed matters more than depth
Debugging complex issues Opus (with thinking) Root cause analysis needs depth

Boris Cherny's rule: "Even though Opus is bigger and slower, since you have to steer it less and it's better at tool use, it is almost always faster than using a smaller model in the end." Route subagents to the right model to control costs: Explore → Haiku, Plan → Sonnet, Security / Architecture → Opus.