Files
holocron/plugins/kyberforge/skills/agent-author/references/plugin-scope.md
Defame1297 4a5c3c0cff 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
2026-08-14 21:13:13 +00:00

3.6 KiB

source_keys
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.