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:
@@ -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.
|
||||
Reference in New Issue
Block a user