GitHub Copilot
Apothem harness adapter for GitHub Copilot (GA).
Vendor: GitHub / Microsoft
Install name: github-copilot
Status: GA
Native config: <project>/.github/copilot-instructions.md
Installation
apothem install --harness github-copilot --project /path/to/projectThe adapter derives the project instructions file from your shared profile and the shared Apothem rules and governance surface, writes Apothem's helpers as Copilot helper profiles in the project (see Helper profiles), and registers two hooks (see Hooks).
It also writes Apothem's skills, and the rules and templates they cite, to your user home, before it touches the project (see Files outside the project).
Files written:
<project>/.github/copilot-instructions.md, the instructions file.<project>/.github/agents/<name>.agent.mdfor each Apothem helper, in the project.<project>/.github/hooks/apothem.json, the hook file, in the project. Your own hook files in that folder are not touched.<project>/.apothem/support/github-copilot/hooks/, the hook scripts, in the project.~/.agents/skills/<name>/SKILL.mdfor each Apothem skill and command, in your user home.~/.config/apothem/rules/and~/.config/apothem/templates/, in your user home.
Files outside the project
The install also writes Apothem's skills to your user home, before it changes anything in the project:
| Folder | What Apothem writes there |
|---|---|
~/.agents/skills/ | One folder with a SKILL.md for each Apothem skill, and one for each Apothem command (a command becomes a skill of the same name). |
~/.config/apothem/rules/, ~/.config/apothem/templates/ | The rules and templates that the skills and the instructions file refer to. |
These folders are shared. They are not private to the project:
- Every project you install
github-copilotinto, and every other Apothem install that names the folder, uses the same copy and writes the same files, so the order you install in does not matter. Several other tools read~/.agents/skills/too; the harness registry lists them. --projectchooses the instructions file to write and which project the install belongs to. It does not change where the skills go.- The install adds no skill or rule file to your repository. The project
gets the instructions file, the helper profile files in
.github/agents/, the hook file.github/hooks/apothem.json, plus the.apothem/folder every project install creates, which also holds the hook scripts. - The home folders are written first. If that fails, for example because a folder in the path is a link that leaves your home directory (a link that stays inside it is followed) or cannot be written, the install stops with the error before anything in the project changes.
- A skill folder with an Apothem skill's name that Apothem did not write is
left alone, and the install prints a warning that names it. Rename or move
it, then run
apothem update.apothem verifyfails while that name is held. - The files add up to a few megabytes.
The install prints a note that names the folders it writes outside --project,
and --dry-run lists them.
Helper profiles
Copilot reads a helper profile from <project>/.github/agents/<name>.agent.md, per
GitHub's reference for these profiles.
The install writes one file per Apothem helper into that folder. It installs for
the project only and writes no ~/.copilot/agents/ folder.
Each file keeps the helper's instructions unchanged and carries these frontmatter keys:
| Key | What Apothem writes |
|---|---|
name, description | The helper's name and description. Copilot requires the description. |
tools | The tools the helper may use, as a list of Copilot tool aliases, for example ["read", "search", "execute"]. |
Copilot's tools key is an allowlist of aliases, and it has no key that denies a
tool. So the helper's allowed tools and its denied tools are combined into the one
list:
| Copilot alias | Covers | Written for a helper that is allowed |
|---|---|---|
read | Read, NotebookRead | Read |
search | Grep, Glob | Grep or Glob |
edit | Edit, MultiEdit, Write, NotebookEdit | Write, Edit or MultiEdit |
execute | Bash, PowerShell | Bash or PowerShell |
web | WebSearch, WebFetch | WebSearch or WebFetch |
todo | TodoWrite | TodoWrite |
Copilot has one more alias, the one that lets a helper start other helpers; no
Apothem helper is allowed to do that, so it is never written. An alias is left out when the
helper denies any tool it covers, because the alias would let the helper use that
tool. A tool with no alias (for example Monitor) is left out. A tool with a
pattern, such as Bash(git status), has no alias form: as an allowed tool it is
left out, and as a denied tool it denies the whole tool. A helper that cannot edit
files keeps that limit: it never gets edit.
If every tool in a helper's list is left out, the file says tools: [], which
gives the helper no tools, rather than omitting the key, which would give it every
tool.
The install writes no model key, so a helper uses the default model, and none of
the other keys Copilot documents (target, disable-model-invocation,
user-invocable, mcp-servers, metadata), a turn limit, or Apothem's version,
updated and portability keys.
Things to know:
.github/agents/is part of your repository. Teammates and Copilot's cloud coding service read the same files, so commit them with the project or list.github/agents/in.gitignore; Apothem does not choose for you.- The cloud coding service does not honor the
webandtodoaliases. Thewebalias covers both web search and page fetches, socitation-auditor,fact-checkerandresearch-scoutcan read and search files there but can neither search the web nor fetch pages. - The Copilot CLI also reads the repository's
.claude/agents/, but not~/.claude/agents/, so the Claude Code install does not reach Copilot. - A file of yours named like an Apothem helper (
<name>.agent.md) is saved under~/.apothem/backups/and then replaced. The uninstall does not put it back. Files with other names are never touched. Copilot's documentation does not say what happens when the folder holds both<name>.mdand<name>.agent.md. - Apothem has not confirmed whether Copilot prefers
.github/agents/or.claude/agents/for one name, or how the cloud coding service and VS Code treat a frontmatter key they do not list.
Hooks
Copilot runs hooks from JSON files in <project>/.github/hooks/, per the
Copilot hooks reference.
The install writes one file there, apothem.json (version 1), with two hooks:
| Event | What runs |
|---|---|
sessionStart | The session bootstrap: session metadata, the skill index, the memory and plan summaries and the standing posture, added to the model's context. |
postToolUse (every tool) | The proactive-compaction tracker. It counts activity and, at most twice per compaction cycle, tells the model to save its state or compact. It is silent otherwise. |
Both add context for the model. Neither blocks a tool call or a session.
Apothem registers no preToolUse guard on Copilot. For preToolUse Copilot reads
only permission fields and a rewritten tool input, never additionalContext (the
field Apothem's guards speak through). A guard registered there would cost a
process start on every tool call and deliver nothing, so the write, edit and shell
guards, the AskUserQuestion check and the session-end protocol stay on the tools
that deliver them. The hooks use Copilot's camelCase event names, because the
reference lists the output fields for those; whether Copilot reads
additionalContext from a PascalCase event is not documented.
Where the files go
| File | What it holds |
|---|---|
<project>/.github/hooks/apothem.json | The two hook registrations. Apothem owns this one file. |
<project>/.apothem/support/github-copilot/hooks/ | The dispatcher script, its helpers and its message files. |
Each hook has a bash command and a powershell command. They run the same
dispatcher; the powershell one has a call operator (&) in front, which
PowerShell needs before a quoted program path. A bash command looks like this,
with your interpreter and project path in place of the two paths:
"/path/to/python" "/path/to/project/.apothem/support/github-copilot/hooks/dispatch.py" --contract copilot sessionStart--contract copilot makes the dispatcher read Copilot's camelCase input and print
{"additionalContext": ...}, which is what Copilot reads for these two events.
Commit with care, and the cloud agent. .github/hooks/ is part of your
repository, and Copilot's cloud coding service reads it. The commands name the
interpreter Apothem found when it ran and the absolute path of the project, and
the scripts are in .apothem/, which a project's .gitignore snippet ignores.
On any other machine, and in the cloud service (which runs only the bash
command), the command finds nothing to run. Copilot logs the failure and the run
goes on, because a failed sessionStart or postToolUse hook does not block.
Add .github/hooks/apothem.json to .gitignore, or commit it only for a team that
shares the same layout. The install does not edit .gitignore and prints this as
a note.
Your own hooks. Hook files of yours in .github/hooks/ are never read or
changed. A hook you add to apothem.json itself stays: an update and an uninstall
replace or remove only the entries whose command runs the Apothem dispatcher
(.apothem/support/github-copilot/hooks/dispatch.py with --contract copilot,
whichever project path it was written under). A hook of yours that only shares
the name, or that runs python -m apothem.conformity.gate, is never taken for
Apothem's. A file that is not valid JSON is saved under ~/.apothem/backups/ and
replaced.
Paths the shell would misread. A project or interpreter path that contains
$, a backtick, a double quote or a backslash is refused before anything is
written: inside the quoted command it would run a different file, or break the
JSON the command is written into. The error names the path; move or rename the
project and run the install again. A space or an apostrophe in a path is fine.
Turning the hooks off. Set APOTHEM_HOOKS_DISABLE=1 in the environment Copilot
runs in to silence the Apothem hooks, or set "disableAllHooks": true in
apothem.json, which skips that one file.
VS Code's older Local hook contract (events with command, windows, linux and
osx fields) is a different format that a version 1 file does not target.
Profile-to-native-config mapping
The adapter reads Apothem's shared profile and renders the repo-wide Copilot
instructions file on every apothem install or apothem update run. The
shared profile is the source of truth; project-local edits to the generated
file are backed up before the next sync replaces the Apothem-managed content.
Inside the Apothem block, the section rendered from your profile (operator, preferences, custom rules, opted-in behaviors, MCP server names) comes first, ahead of the shared governance text. GitHub notes that shorter instruction files are more likely to be processed in full by code review (Customizing code review), so the part that is specific to you leads the file.
Compatibility notes
GitHub Copilot does not expose a file-based user-global instructions path for
this adapter to manage. Apothem targets the documented project-scope
instructions file and leaves IDE-level user settings operator-owned. It writes
one hook file, .github/hooks/apothem.json, and no other file in
.github/hooks/.
Within the Apothem repository, .github/copilot-instructions.md is one voice
among that repository's assistant instruction surfaces. In a checkout of that
repository, the conformity gate's multi-surface coherence check compares the
shared claims in AGENTS.md, CLAUDE.md, and .github/copilot-instructions.md.
It reports a shared claim that one of the three files leaves out, and a file that
contradicts a claim AGENTS.md makes. The check does not read the
instructions file Apothem writes into your project. The gate is advisory by
default: it reports findings and exits 0.
GitHub Copilot lists ~/.agents/skills/ among its personal skill locations,
so the skills the install writes are on your machine for Copilot to load.
Surfaces that run on GitHub, the cloud coding service and code review, run
elsewhere and do not see your home folder, which is why the instructions file carries the
disciplines itself. Apothem has not confirmed how Copilot treats a SKILL.md
header key it does not list; the skills carry user-invocable,
disable-model-invocation, allowed-tools, argument-hint, and a metadata
map.
Verification
apothem verify --harness github-copilot --project /path/to/projectThe verify command confirms that:
- The native config exists at the expected path.
- Each managed target exists, the
.github/agents/folder included; managed files are non-empty, and JSON or YAML configs parse. Add--profile PATHto also confirm that the installed files match that profile. For.github/agents/the check is that the folder exists, not that each helper file is in it;apothem diff --harness github-copilot --project /path/to/projectlists the helper files that are missing or out of date. The hook file.github/hooks/apothem.jsonmust exist, be non-empty and parse as JSON and hold an entry that runs the Apothem dispatcher, and the hook scripts must be in.apothem/support/github-copilot/hooks/. The check does not run the hooks. - Every Apothem skill folder is in place with a
SKILL.md, whichever install wrote it, and no skill folder with an Apothem name belongs to something Apothem did not write. A failed check names the missing or foreign folders. - The adapter-specific verification routine reports success.
Updating
apothem update --harness github-copilot --project /path/to/projectRe-derives the project instructions file from the current shared profile state.
The update also rewrites any skill folder whose files differ from the current ones.
If you installed with an earlier release that wrote no skills, the update adds them.
It rewrites helper profile files that differ from the current ones, and adds any that are missing.
It also refreshes the hook scripts and the Apothem hooks in .github/hooks/apothem.json,
keeping any hook of yours in that file.
Uninstalling
apothem uninstall --harness github-copilot --project /path/to/projectRemoves the Apothem block from <project>/.github/copilot-instructions.md and
keeps any text outside it. The file is deleted only when nothing else remains in
it. Before the change, a timestamped copy of the file is saved under
~/.apothem/backups/. The shared profile YAML and Apothem engine are
unaffected.
The uninstall also removes the helper profile files it wrote in <project>/.github/agents/
and keeps any other file there; the folder is removed when it is left empty.
It removes the Apothem hooks from <project>/.github/hooks/apothem.json, recognising
them by the dispatcher path in their command, so it works without an install record,
and keeps any hook of yours in that file. The file is deleted when nothing else is in
it, and your other hook files are not touched. If the file has comments the
uninstall cannot read, it leaves the file as it is and reports the hooks as
skipped, with the reason; remove the Apothem entries by hand. The hook scripts in
<project>/.apothem/support/github-copilot/hooks/ go too.
It removes the skill folders it wrote in ~/.agents/skills/ and the
rules and templates in ~/.config/apothem/, but only when no other Apothem
install still uses them. Another project, or another tool that shares the
folder, may. In that case the uninstall keeps the folders, prints which install
uses them, and the last uninstall removes them. Files you added to those
folders stay, and a folder left empty is removed. Each
folder is backed up under ~/.apothem/backups/ before it is removed.
Conformity gate
python -m apothem.conformity.gate --all .The --all run covers the standalone validators. It does not run the
multi-surface coherence check described under Compatibility notes. To run that
check by name in a checkout:
python -m apothem.conformity.gate --check multi-surface-coherence-grep AGENTS.mdTroubleshooting
| Symptom | Fix |
|---|---|
| Config file not found | Re-run apothem install --harness github-copilot --project /path/to/project |
| Verification failed | Run apothem update --harness github-copilot --project /path/to/project, then verify again |
| Copilot lists none of the Apothem helpers | Check that .github/agents/ holds the .agent.md files and that they are on the branch you are using. Run apothem diff --harness github-copilot --project /path/to/project: a pending line for the .github/agents folder means helper files are missing or out of date, so run apothem update --harness github-copilot --project /path/to/project. apothem verify is not a test of this: it passes when .github/agents/ exists, even with no helper file in it |
| The Apothem hooks do not run | Check that .github/hooks/apothem.json is on the branch you are using and that .apothem/support/github-copilot/hooks/ exists on this machine; the commands name the interpreter and project path of the machine that ran the install, so run apothem install --harness github-copilot --project /path/to/project on each machine. Copilot's cloud coding service runs only the bash command, with no interpreter at that path |
apothem verify names a missing skill folder | Run apothem install --harness github-copilot --project /path/to/project; it restores the folder |
| An install or update warns that it skipped a skill folder | A folder with an Apothem skill's name already exists in the skills folder and Apothem did not write it. Rename or move it, then run apothem update |
| An install stops before it changes the project | A write in your home failed. Read the error, fix the folder it names (a link that leaves your home directory, a file where a folder belongs, or a read-only folder), and install again |
| Unexpected config content | Check ~/.config/apothem/profile.yaml or --profile PATH, then re-run apothem update --harness github-copilot --project /path/to/project |
Configuration knobs
| Flag | Default | Description |
|---|---|---|
--dry-run | false | Preview install without writing files. |
See also
- All harnesses — the full catalog of supported tools
- Install guide — install Apothem into this harness
apothem harnessesreference — list and inspect adapters from the CLI