feat(kyberforge): enforce the ADR-0020 context contract for skills and agents

Skill name+description pairs are preloaded into every session, costing
~6,200 tokens across 39 skills before any skill is invoked. The authoring
rules mandated that growth: skill-author:104 and description-quality.md:21
both required padding, while skill-author:102 (the deflating rule) had no
FAIL condition behind it.

Gates (blocking, no baseline file):
- description 250 chars SUGGESTION / 400 FAIL, measured on the folded
  YAML value
- body-only 600 words SUGGESTION / 900 FAIL, independent of the unchanged
  whole-file 2770-word / 500-line spec backstop
- every boundary-clause routing target must resolve to a real skill or
  agent; catches skill-improve, neuledge-context and gitea-labels
- agents take the description gates but deliberately no body gate; a test
  pins that absence

Vale: DescriptionOpener widened to ^This\b, new CompositionNote rule
banning architecture notes from descriptions. 10 hits, 0 false positives.

Kyberforge's own four skills retrofitted: descriptions 3,364 -> 938 chars
(-72%), bodies 8,306 -> 2,487 words (-70%), all via the apm-workflow
dispatch pattern. Fixes the skill-improve dangling route and the
agent-author misroute to manual review.

Also fixes a pre-existing false positive where any line-initial 'read '
was flagged as interactive input, which had already caused two scripts to
be rewritten around it.

Refs: ADR-0020
This commit is contained in:
2026-08-14 21:13:13 +00:00
parent 1c6eababb0
commit 4a5c3c0cff
104 changed files with 6272 additions and 1880 deletions

View File

@@ -4,14 +4,52 @@ source_keys: []
# references/
## create.md
The create flow, loaded from SKILL.md Step 1 when no agent file exists at the target path.
Covers: prerequisites, the scaffold script and its scope walk-up, what to fill in at every scope,
and populating or deleting the package-root `sources.md`.
## improve.md
The improve flow, loaded from SKILL.md Step 1 when a file exists and at least one improvement
signal is present. Covers: signal verification, partial-pair recovery, root-cause grouping,
generalizing rather than patching, delegation over growth, and the ADR-0020 retrofit rule.
## contract.md
The description and body contract, loaded from SKILL.md Step 3 before any description is written
or any body restructured. Covers: the three-part description shape, banned description content,
boundary-target resolution, the 250/400 length tiers, the body role-instruction pattern, the
delegation rule that replaces a body word gate, and the invocation axis.
## plugin-scope.md
Field rules and the pre-audit checklist for the single vendor-neutral `.apm/agents/<name>.agent.md`
file. Loaded from SKILL.md Step 2 when the scaffold resolves plugin/APM scope.
## project-user-scope.md
Field rules and the pre-audit checklist for the Claude Code `.md` + Copilot `.agent.md` pair,
including the two distinct Copilot formats. Loaded from SKILL.md Step 2 when the scaffold resolves
project or user scope.
## deployment-modes.md
Agent scope hierarchy, precedence rules, and per-scope restrictions. Covers: which frontmatter fields a plugin/APM-scope agent may carry and the allowlist-vs-denylist shape rule that decides it (deferring to `agent-audit`'s `references/field-inventory.md` for the list itself), scoped identifiers for plugin subdirectory agents, cache isolation behaviour, and Copilot CLI path conventions. Loaded conditionally from SKILL.md when the destination is a plugin directory.
Scope hierarchy and precedence, scoped identifiers for plugin subdirectory agents, cache isolation
behaviour, and Copilot CLI path conventions. Loaded from SKILL.md Step 2 when precedence, paths or
cache isolation matter to the run.
## scripts.md
Conventions for the `new-agent.sh` scaffold script and any future scripts added to this skill. Covers: what scripts should and should not do, file placement, error handling, template variable conventions, and the no-interactive-prompts rule.
Conventions for the `new-agent.sh` scaffold script, the templates it copies, and any future script
in this skill. Loaded from `create.md` Step 1 when the script or a template has to change. Covers:
the no-interactive-prompts rule, structured output, idempotency, template variables, file
placement, error messages, and the no-restated-field-roster rule that `tests/new-agent.bats`
enforces.
## sources.md
Research provenance record for this skill. Lists the upstream research sources (claude-code-plugins and github-copilot-plugins research docs) that informed SKILL.md, the templates, and the deployment-modes reference. Used by `skill-audit` to validate the provenance chain.
Research provenance record for this skill. Lists the upstream research sources
(claude-code-plugins and github-copilot-plugins research docs) that informed SKILL.md and the
reference files. Used by `skill-audit` to validate the provenance chain.

View File

@@ -0,0 +1,117 @@
---
source_keys:
- claude-code-subagents-docs
- github-custom-agents-configuration
---
# The agent description and body contract
House contract, set by ADR-0020. The counts and the boundary targets are enforced by
`agent-audit`'s `scripts/validate.sh`; the prose patterns by the Vale styles it bundles; the
judgment calls by its reference files.
## Why the budget exists
An agent's `name` and `description` is loaded into every session's context at startup, whether or
not the agent is ever delegated to — the same cost a skill's description carries, so agents take
the same numbers. The body is different: it is not loaded into the caller's conversation at all,
it *becomes the system prompt of a fresh context* when the agent runs. That is why the body has no
word gate here and a skill body has one.
## Description
A description carries exactly three things:
1. **Trigger clause** — when to delegate, imperative: "Use when …", never "This agent …". Describe
the user's intent and the triggering condition, not the agent's internal mechanics.
2. **At most one capability clause** — what it does, one clause, no enumeration. Be specific
("reviews a diff for injected credentials", not "helps with security").
3. **Boundary clause** — form: `Not <thing> -> <name>.` Add one only where a near-miss agent or
skill could steal delegations.
Banned from a description; move it to the body or to `README.md`:
- Capability enumeration or feature lists
- Per-scope emission mechanics — which files the author skill writes at which scope changes no
delegation decision
- Output-format detail ("Produces a compact findings report with Why and Fix per finding")
- Composition or architecture notes ("composes X rather than duplicating Y", "cross-cutting")
- Implementation detail ("Self-validates via a bundled deterministic script")
- Restating the same trigger twice in two registers — a verb list, then the same verbs re-quoted
as user phrasings. This is a FAIL, not a suggestion.
**Do not open with an action verb.** "Reviews…", "Analyzes…", "Generates…" was the old house rule
and ADR-0020 deleted it: the opener is `Use when`, matching every skill in this corpus, so one
router reads one shape.
**"Use proactively" is conditional.** Add it only where the runtime should delegate without the
user naming the agent — an agent invoked by name does not need it, and it costs activations
elsewhere when added by reflex. The same conditional governs indirect triggers ("even if the user
doesn't say X"): add one only where the user's natural phrasing genuinely omits the domain word.
**Boundary targets must resolve.** The name after the arrow is checked against real skills under
`plugins/*/.apm/skills/<name>/` and real agents under `plugins/*/.apm/agents/<name>.agent.md`. A
target that does not exist sends the router nowhere. Verify it before writing it — do not invent a
plausible sibling.
**Length.** 250 characters SUGGESTION, 400 characters FAIL, counting the frontmatter value only
with YAML folding resolved. Treat 250 as the target: the SUGGESTION tier is what moves the corpus
average, the FAIL tier only stops outliers.
## Body
Write the body as a direct role instruction, addressed to the agent:
````markdown
You are a <role>. When invoked, <primary action>.
## Inputs
<what the agent is given: files, context, parameters>
## Process
<ordered steps; be explicit where ordering matters>
## Output
<what it produces: format, location, structure>
````
One job per agent. An agent covering two jobs gets delegated to for the wrong one.
**Delegation discipline replaces the word gate.** A plugin/APM agent is a single file with no
sibling `references/` directory: it cannot disclose progressively to itself, so its only way to
stay short is to *invoke* rather than *restate*. A body that transcribes a procedure a skill it
can invoke already owns is an `agent-audit` FAIL, and the fix is one line — "invoke `<skill>`".
- Restating: "To commit, check the message against Conventional Commits: type, scope,
description; header under 100 chars; …"
- Delegating: "Author commits with `git-commits`."
The same holds for a procedure another agent owns. What belongs in the body is what no invocable
skill covers: the agent's role, its boundaries, the order it works in, and the format it returns.
**State a read-only boundary in prose, not only in frontmatter.** `disallowedTools` denies the
tools it names and nothing else — never `Bash`, which an agent with no `tools` field inherits — so
an agent fenced only in frontmatter can still write through a shell redirect.
## Invocation axis
Decide before writing the description whether the agent is model-delegated (the runtime picks it)
or reached only by name (`@agent-<name>`).
Only Copilot's cloud/IDE format expresses that in frontmatter: `disable-model-invocation: true`
requires explicit invocation, and `user-invocable: false` hides an agent from manual invocation.
Both live in `.github/copilot/agents/<name>.md` and are inert in the CLI format. Claude Code has
no equivalent field, and neither does the vendor-neutral plugin/APM file, so at those scopes a
name-invoked agent still needs a description precise enough not to steal delegations — the
boundary clause is doing that work.
## One gate, two measurements
| Gate | SUGGESTION | FAIL | Counts |
|---|---|---|---|
| description | 250 chars | 400 chars | the `description:` value only |
| body (Copilot limit) | 30,000 chars | — | the body only; content past it is truncated silently |
The 30,000-character Copilot ceiling is a runtime truncation limit, not a quality target, and it
applies to a plugin/APM file too — that file compiles into a real Copilot agent downstream. An
agent body long enough to approach it has a delegation defect, not a length problem.

View File

@@ -0,0 +1,93 @@
---
source_keys:
- context7-websites-code-claude
- claude-code-subagents-docs
- github-plugins-creating
---
# Creating a new agent
Return to `SKILL.md` Step 4 once Step 3 below is done — validation, the version bump and commit
verification are shared with the improve flow and are not repeated here.
## Prerequisites
Before touching the filesystem, confirm you have:
- [ ] Agent name (kebab-case, e.g. `code-reviewer`)
- [ ] Root directory — a path inside a package for plugin/APM scope, a project root, or `~` for
user scope
- [ ] Agent purpose — one sentence describing the task this agent handles
- [ ] Trigger condition — when should the runtime delegate to this agent?
If any are missing, stop and ask before proceeding.
`agent-audit` runs the validation in `SKILL.md` Step 4. It ships with the kyberforge plugin and
is co-installed with this skill; if it is unavailable, stop and ask the user to install
kyberforge before continuing.
Design for one job per agent. An agent covering two jobs is delegated to for the wrong one.
## Step 1 — Scaffold
```bash
bash scripts/new-agent.sh <name> <root>
```
Examples:
```bash
bash scripts/new-agent.sh code-reviewer packages/my-package/ # plugin/APM scope if packages/my-package/apm.yml has a type: field
bash scripts/new-agent.sh deploy-assistant .
bash scripts/new-agent.sh security-reviewer ~
```
The script resolves scope itself and prints which one it used and every path it wrote — read that
output rather than predicting it. It walks up from `<root>` for the nearest ancestor `apm.yml`
carrying a top-level `type:` field (`instructions`/`skill`/`hybrid`/`prompts`), which marks a
package root and means plugin/APM scope. An `apm.yml` with no `type:` is a marketplace-only
manifest: the walk skips it and keeps going. With no such manifest found, `<root>` being exactly
`~` (checked directly, no walk-up) is user scope and anything else is project scope. A bare
`plugin.json` no longer signals plugin scope — that path was replaced outright, not made
dual-mode, and falls through to project scope.
The script is file-by-file no-op: it skips any file that already exists, so re-running it to
complete a partial pair is safe.
If the script or a template under `assets/templates/` has to change to support this agent — a new
scope, a new scaffolded field, different output — read `references/scripts.md` first. Its
conventions are asserted by `tests/new-agent.bats`, and an edit that ignores them fails the suite.
## Step 2 — Fill in the file(s)
Take the scope the script reported and read the matching reference — `SKILL.md` Step 2 has the
table. That file carries the field rules and the pre-audit checklist for this scope; the other one
describes fields this run cannot use.
Every scaffolded file, at every scope:
1. Replace each `FILL IN:` placeholder.
2. Delete every `<!-- ... -->` template comment from the frontmatter. `apm compile` copies plugin
frontmatter verbatim and HTML comments are not valid YAML, so a leftover comment breaks the
file downstream on both harnesses.
3. Write the `description` against `references/contract.md` and the system prompt body against its
Body section.
## Step 3 — Populate or delete `sources.md`
Plugin/APM scope only — skip at project and user scope, which have no package root to hold the
file.
The scaffold writes a commented `sources.md` skeleton at the package root, alongside `apm.yml` and
not inside `.apm/agents/`, so that tooling scanning that directory for agent definitions does not
treat it as an agent missing its frontmatter (ADR-0010).
If a research `sources.md` is present in the conversation context, filter it to entries with
`` `extracted` `` status, work out which agent file each one contributed to, and fill in the
skeleton following the commented format already in the file. Paths in `Contributing files:` are
relative to the package root. Each slug must match an H2 heading and must also appear in the
`source_keys` list of every file named under its `Contributing files:`.
If no research sources are in context, delete `sources.md`.
Then return to `SKILL.md` Step 4.

View File

@@ -22,13 +22,14 @@ Agent definitions deploy at three scopes and behave differently at each. The sco
When the same agent `name` appears at multiple scopes, **user scope wins over project scope wins over plugin scope** in Claude Code. In Copilot CLI, repo-level agents override enterprise and org-level; home-directory (user) agents override repo-level on name collision.
## Plugin scope restrictions
## Which fields exist where
Plugin/APM agents (`.apm/agents/<name>.agent.md`) carry only the fields in the `apm-agent-allowlist` section of `agent-audit`'s `references/field-inventory.md`. That section is the authoritative list — `agent-audit`'s `validate.sh` reads it from there as data, and it changes — so consult it rather than any restatement of it. `apm compile` copies this frontmatter verbatim to both the Claude Code and Copilot CLI compile targets with no per-target integrator, so a harness-specific value is guaranteed wrong on at least one target (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 under verbatim copy one value is wrong on one target. It stays out. `disallowedTools` is a **denylist**, and denying by name has no such conflict: a name the other harness does not recognise denies nothing, so the worst case is that the fence is absent there, never that a capability is wrongly granted. That asymmetry is why the denylist is admitted where the allowlist is not (ADR-0016's 2026-08-14 amendment). Claude Code honours it for plugin subagents — `docs/research/docs/claude-code-plugins/agent-definition.md:99` names the three fields plugin agents silently ignore (`hooks`, `mcpServers`, `permissionMode`) and `disallowedTools` is not among them. It is a partial fence: it denies only the tools it names, not `Bash`, which a plugin-scope agent with no `tools` inherits — so state read-only intent in the body too.
This makes the old "silently ignored at plugin scope" framing moot for the excluded fields. It's not that `hooks`, `mcpServers`, `permissionMode`, `tools`, `isolation`, `maxTurns`, `effort`, `memory`, `skills`, `color`, `initialPrompt`, or `background` are merely ignored at this scope — they are never written to the file at all. Copy the agent to `.claude/agents/` (project scope) or `~/.claude/agents/` (user scope) to use any of them.
Field rules are per scope and live with the scope: `references/plugin-scope.md` for the single
vendor-neutral file, `references/project-user-scope.md` for the Claude Code / Copilot pair. Read
one, not both. The short version is that plugin/APM frontmatter is an allowlist read from
`agent-audit`'s `references/field-inventory.md`, narrow because `apm compile` copies frontmatter
verbatim to every target (ADR-0016), while project and user scope carry the full per-provider
field sets.
## Scoped identifiers (Claude Code plugin agents only)

View File

@@ -0,0 +1,76 @@
---
source_keys:
- claude-code-subagents-docs
---
# Improving an existing agent
Return to `SKILL.md` Step 4 once Step 4 below is done — validation, the version bump and commit
verification are shared with the create flow and are not repeated here.
## Step 1 — Verify inputs
Confirm the agent file (or, at project and user scope, the pair) exists and that at least one
improvement signal is present in the conversation or in a referenced file.
If no signals are present, stop: "This skill applies existing signals to an agent. For a blind
review, run `agent-audit` instead."
`agent-audit` runs the validation in `SKILL.md` Step 4 and is co-installed with this skill; if
it is unavailable, stop and ask the user to install the kyberforge plugin before continuing.
**Partial pair — project and user scope only.** If one provider file exists and the other does
not, scaffold the missing one with `bash scripts/new-agent.sh <name> <root>` (file-by-file no-op)
and continue. Plugin/APM scope is a single file and has no partial state.
## Step 2 — Gather and group signals
Read the current file(s), then collect every signal from the conversation and from any path the
user referenced.
Group signals by **root cause**, not by symptom. Patching per symptom is the default failure mode:
three complaints often trace to one missing instruction. Ask: "What single gap in this agent
causes this cluster?" One root cause, one fix.
```text
Example:
- User feedback: the agent keeps trying to push to the remote
- Session context: no scope boundary in the system prompt
→ Root cause: the system prompt has no git scope constraint → fix: add an explicit boundary
```
## Step 3 — Announce planned changes
Before editing, state which root causes were identified, what evidence supports each, and which
files will change. Then proceed — edits are reversible via git, so no approval checkpoint is
needed.
## Step 4 — Apply changes
Edit whichever file the signals point to.
**Generalize, do not patch.** Fix the underlying gap, not the one example that failed. A fix
scoped to the cases you have seen overfits and performs worse on new input.
**Delegate rather than grow.** An agent body has no word ceiling, but a body that restates a
procedure a skill it can invoke already owns is an `agent-audit` FAIL. When a signal reports a
missing procedure, check first whether an installed skill owns it and name that skill instead of
transcribing it. See `references/contract.md`.
**Explain the why.** Reasoning-based instructions outperform rigid directives. A rule written in
all caps (ALWAYS/NEVER) is usually better reframed as why the behaviour matters, so the agent can
apply judgment at the edges.
**Retrofit before extending.** Any agent predating ADR-0020 has to meet the description contract
before any other edit lands — the gates are hot and carry no baseline file, so a one-line fix to a
non-compliant agent cannot be committed until its description meets `references/contract.md`.
Treat that retrofit as part of the same change, not a follow-up.
**Re-check the scope rules.** Read the reference for the resolved scope (`SKILL.md` Step 2) and
confirm the edit introduced no field that scope forbids, and dropped no `disallowedTools` fence
that was already there.
If the edit adds or removes research-sourced content, update `source_keys` in the edited file and
the matching `sources.md` entry — the create flow's Step 3 has the rules.
Then return to `SKILL.md` Step 4.

View File

@@ -0,0 +1,67 @@
---
source_keys:
- context7-websites-code-claude
- claude-code-plugins-docs
---
# Plugin/APM scope — the single vendor-neutral file
One file, no counterpart: `<package-root>/.apm/agents/<name>.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`
Then return to the flow reference you came from.

View File

@@ -0,0 +1,106 @@
---
source_keys:
- claude-code-subagents-docs
- context7-github-en-copilot
- github-custom-agents-configuration
- github-cli-plugin-reference
---
# Project and user scope — the Claude Code / Copilot pair
Two files per agent, written in one pass and kept in step: a Claude Code `.md` and a Copilot CLI
`.agent.md`. The system prompt body is the same in both — the agent's task does not change with
the provider. The frontmatter is not.
| Scope | Claude Code | Copilot CLI |
|---|---|---|
| Project | `.claude/agents/<name>.md` | `.github/agents/<name>.agent.md` |
| User | `~/.claude/agents/<name>.md` | `~/.copilot/agents/<name>.agent.md` |
## Claude Code file
**`name`** — lowercase letters and hyphens only, unique within the scope. Claude Code discards a
duplicate silently.
**`description`** — write it against `references/contract.md`. It is the primary signal for
autonomous delegation.
**`tools`** — an allowlist; omit it to inherit every tool from the parent. Use `Agent(type1,type2)`
to restrict which subagent types this agent may spawn, and omit `Agent` entirely to stop it
spawning any. Five tools reach no subagent whatever this field says — `AskUserQuestion`,
`EnterPlanMode`, `ExitPlanMode`, `ScheduleWakeup` and `WaitForMcpServers` — so listing one buys
nothing. The single exception is `ExitPlanMode`, available when the parent session runs
`permissionMode: plan`.
**`disallowedTools`** — a denylist, applied before `tools` and taking precedence over it. Supports
`mcp__<server>`, `mcp__<server>__*` and `mcp__*` globs. Both a YAML list and a delimited string
are accepted; this repo writes the comma-separated string form (`disallowedTools: Edit, Write,
NotebookEdit`) — match it.
**`model`** — set it when the agent needs a different capability tier (`haiku` for fast lookups,
`opus` for deep reasoning). Resolution order is `CLAUDE_CODE_SUBAGENT_MODEL` → the per-invocation
parameter → this field → the main session model, so the frontmatter value is a low-priority
default rather than a guarantee.
Optional fields worth considering, none of which exist at plugin/APM scope:
- `maxTurns` — cap agentic turns on a bounded task, to stop a runaway
- `effort` — `low` for a single lookup, `high` or above for multi-file analysis; omit to inherit
- `memory` — `user`, `project` or `local`; only when cross-session state is genuinely needed
- `isolation: worktree` — only when the agent modifies files and needs an isolated copy
- `skills` — skill names preloaded at agent startup; unrelated to the `source_keys` metadata field
- `color` — the UI tile colour (`red`, `blue`, `green`, `yellow`, `purple`, `orange`, `pink`,
`cyan`)
- `background` — `true` forces background execution
- `initialPrompt` — auto-submitted as the first turn when the agent activates as the main session
thread; set it only for a main-thread agent, never for a subagent
`hooks`, `mcpServers` and `permissionMode` are honoured at these two scopes and nowhere else — a
plugin agent carrying them is ignored silently.
A subdirectory under `agents/` does not affect the agent's name at these scopes; it does at plugin
scope, which is one reason `references/deployment-modes.md` recommends keeping agents flat.
## Copilot file
Two Copilot formats exist, with different paths and different field sets. Pick one:
**CLI format** — what the scaffold writes.
- Path: `.github/agents/<name>.agent.md` (project) or `~/.copilot/agents/<name>.agent.md` (user)
- The `.agent.md` extension is mandatory: Copilot CLI does not pick up a plain `.md` file in
`agents/`, and fails silently rather than reporting it
- Fields: `name` (required, must equal the filename stem), `description` (required), `tools`
(optional)
- `tools` uses Copilot aliases, not Claude tool names: `execute` (shell), `read`, `edit`,
`search`, `agent`, `web`; MCP tools as `server-name/tool-name` or `server-name/*`
**Cloud/IDE format** — for Copilot Chat in VS Code or on GitHub.com.
- Path: `.github/copilot/agents/<name>.md` — a plain `.md`, in a different directory
- Adds `target` (`vscode`, `github-copilot`, or omit for both), `user-invocable`,
`disable-model-invocation` and `mcp-servers` (processed by the cloud runtime, ignored in VS
Code). These four are inert in the CLI format — do not write them there
- This is the only format that can express the invocation axis in frontmatter; see the Invocation
axis section of `references/contract.md`
Both formats truncate a body past **30,000 characters** silently.
Copilot has no `permissionMode`, `maxTurns`, `isolation`, `memory`, `effort`, `hooks` or
`mcpServers`. Never let those cross over from the Claude Code file.
## Before invoking `agent-audit`
Both files:
- [ ] `name` present and kebab-case; `description` written to `references/contract.md`
- [ ] System prompt body present, non-empty and equivalent across the pair
- [ ] No `FILL IN:` placeholder and no `<!-- ... -->` template comment left
Copilot file only:
- [ ] Extension is `.agent.md` (CLI format), and `name` matches the filename stem
- [ ] No Claude Code-only field present
- [ ] Body under 30,000 characters
Then return to the flow reference you came from.

View File

@@ -19,7 +19,7 @@ source_keys:
- **URL:** context7:/websites/code_claude
- **Research doc:** plugins/kyberforge/docs/research/docs/claude-code-plugins/sources.md
- **Description:** Official Claude Code documentation site indexed by Context7 — plugin manifest schema, subagent definition types, marketplace JSON format, agent markdown file format
- **Contributing files:** SKILL.md, references/deployment-modes.md
- **Contributing files:** SKILL.md, references/create.md, references/deployment-modes.md, references/plugin-scope.md
- **Status:** `extracted`
## claude-code-plugins-docs
@@ -27,7 +27,7 @@ source_keys:
- **URL:** https://code.claude.com/docs/en/plugins
- **Research doc:** plugins/kyberforge/docs/research/docs/claude-code-plugins/sources.md
- **Description:** Official Claude Code plugin authoring guide — plugin structure, manifest fields, loading methods, skill namespacing, agent activation, marketplace submission
- **Contributing files:** SKILL.md, references/deployment-modes.md
- **Contributing files:** SKILL.md, references/deployment-modes.md, references/plugin-scope.md
- **Status:** `extracted`
## claude-code-subagents-docs
@@ -35,7 +35,7 @@ source_keys:
- **URL:** https://code.claude.com/docs/en/sub-agents
- **Research doc:** plugins/kyberforge/docs/research/docs/claude-code-plugins/sources.md
- **Description:** Official Claude Code subagent reference — definition format, all frontmatter fields, scope priority, built-in agents, CLI flags, environment variables, known limitations
- **Contributing files:** SKILL.md, references/deployment-modes.md
- **Contributing files:** SKILL.md, references/create.md, references/improve.md, references/contract.md, references/deployment-modes.md, references/project-user-scope.md
- **Status:** `extracted`
## context7-github-en-copilot
@@ -43,7 +43,7 @@ source_keys:
- **URL:** context7:/websites/github_en_copilot
- **Research doc:** plugins/kyberforge/docs/research/docs/github-copilot-plugins/sources.md
- **Description:** Official GitHub Copilot documentation indexed by Context7; covers CLI plugins, custom agents, SDK, and marketplace
- **Contributing files:** SKILL.md, references/deployment-modes.md
- **Contributing files:** references/deployment-modes.md, references/project-user-scope.md
- **Status:** `extracted`
## github-custom-agents-configuration
@@ -51,7 +51,7 @@ source_keys:
- **URL:** https://docs.github.com/en/copilot/reference/custom-agents-configuration
- **Research doc:** plugins/kyberforge/docs/research/docs/github-copilot-plugins/sources.md
- **Description:** Reference for cloud and IDE custom agent definition format — frontmatter fields, tool aliases, MCP server config, secrets interpolation, scoping hierarchy
- **Contributing files:** SKILL.md, references/deployment-modes.md
- **Contributing files:** references/contract.md, references/deployment-modes.md, references/project-user-scope.md
- **Status:** `extracted`
## github-cli-plugin-reference
@@ -59,7 +59,7 @@ source_keys:
- **URL:** https://docs.github.com/en/copilot/reference/copilot-cli-reference/cli-plugin-reference
- **Research doc:** plugins/kyberforge/docs/research/docs/github-copilot-plugins/sources.md
- **Description:** Full CLI plugin reference — plugin.json schema, marketplace.json schema, all CLI commands and flags, install specification formats, loading precedence, env vars, LSP config
- **Contributing files:** SKILL.md, references/deployment-modes.md
- **Contributing files:** references/deployment-modes.md, references/project-user-scope.md
- **Status:** `extracted`
## github-plugins-creating
@@ -67,7 +67,7 @@ source_keys:
- **URL:** https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/plugins-creating
- **Research doc:** plugins/kyberforge/docs/research/docs/github-copilot-plugins/sources.md
- **Description:** How-to for creating Copilot CLI plugins — plugin structure, agent and skill authoring, hooks format, MCP config, development lifecycle
- **Contributing files:** SKILL.md
- **Contributing files:** references/create.md
- **Status:** `extracted`
## github-plugins-finding-installing