--- source_keys: - context7-websites-code-claude - claude-code-plugins-docs --- # Plugin/APM scope — the single vendor-neutral file One file, no counterpart: `/.apm/agents/.agent.md`. `apm compile` emits it to both the Claude Code and the Copilot CLI target. The `.agent.md` extension here is convention, not a Copilot marker — the file is vendor-neutral. ## Frontmatter The permitted keys are the `apm-agent-allowlist` section of `agent-audit`'s `references/field-inventory.md`. Read them from there as data — that section is the single source of truth, `agent-audit`'s `validate.sh` parses it at load time, and it changes. Any restatement of the roster, here or in a template or in script output, goes stale one step further out than the list itself. - `name` — kebab-case, must equal the filename stem, unique within the scope. - `description` — write it against `references/contract.md`. - Everything else — check the allowlist section before adding a key. A key outside it fails the audit. **Why the list is narrow.** `apm compile` copies frontmatter verbatim to every target with no per-target integrator, so a harness-specific value is wrong on at least one of them (ADR-0016). The rule is about a field's *shape*, not a fixed roster: - `tools` is an **allowlist** whose vocabulary differs per harness — Claude Code names its own tools, Copilot CLI uses aliases (`execute`/`read`/`edit`/`search`/`agent`/`web`) — so one value is wrong on one target. It stays out. Omitting it means inherit-all-tools on both, which is never wrong. - `disallowedTools` is a **denylist**, and denying by name cannot fail that way: a name the other harness does not recognise denies nothing, so the worst case is a missing fence, never a wrongly granted capability. That asymmetry is the whole exception (ADR-0016's 2026-08-14 amendment). Claude Code honours it for plugin subagents; the three fields plugin agents do silently ignore are `hooks`, `mcpServers` and `permissionMode`, and this is not one of them. Copilot's handling of the key is unconfirmed, which ADR-0016 accepts as a stated risk. - The Claude-only knobs (`isolation`, `maxTurns`, `effort`, `memory`, `permissionMode`, `skills`, `color`, `initialPrompt`, `background`, `hooks`, `mcpServers`) have no Copilot equivalent and are never written to this file at all. "Silently ignored at plugin scope" is the wrong framing: they are absent, not tolerated. To use any of them, copy the agent to `.claude/agents/` (project scope) or `~/.claude/agents/` (user scope). Write `disallowedTools` on every read-only plugin-scope agent — and say the agent is read-only in the body as well, because the fence does not cover the inherited `Bash` tool. `source_keys` is provenance metadata, not a runtime field: both harnesses ignore it. Add it only when research sources informed the agent, with slugs matching H2 headings in the package root's `sources.md`. ## Body Follow the Body section of `references/contract.md`: role instruction, one job, and delegation to installed skills instead of transcribed procedure. ## Before invoking `agent-audit` - [ ] `name` kebab-case, matching the filename stem, unique in scope - [ ] `description` written to `references/contract.md` - [ ] Every frontmatter key present in the `apm-agent-allowlist` section — in particular no `tools` - [ ] No `FILL IN:` placeholder and no `` template comment anywhere in the file - [ ] System prompt body non-empty, and a read-only agent says so in prose as well as in `disallowedTools` - [ ] Body covers all four required elements: inputs expected, process steps, output format, **error handling** — what the agent does on malformed, missing or contradictory input Then return to the flow reference you came from.