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
3.6 KiB
source_keys
| source_keys | ||
|---|---|---|
|
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 againstreferences/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:
toolsis 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.disallowedToolsis 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 arehooks,mcpServersandpermissionMode, 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
namekebab-case, matching the filename stem, unique in scopedescriptionwritten toreferences/contract.md- Every frontmatter key present in the
apm-agent-allowlistsection — in particular notools - 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.