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
7.7 KiB
source_keys
| source_keys | |||||
|---|---|---|---|---|---|
|
Creating a new skill
Return to SKILL.md Step 4 once Step 6 below is done — validation, versioning and commit
verification are shared with the improve flow and are not repeated here.
Prerequisites
Run /grill-me on the skill's design and research the target domain first. Share those outputs
in this conversation: grill context, research docs, examples, constraints.
Design for one coherent user intent — skills too narrow force multiple loads per task; too broad are hard to activate precisely.
Before touching the filesystem, verify you have:
- A clear purpose — what specific task will this skill handle?
- Trigger scenarios — when should an agent activate it?
- Skill name (kebab-case) and destination path
If any are missing, stop and ask the user before proceeding.
Requires /skill-audit — used in SKILL.md Step 4 for final validation. Both skills ship in
the kyberforge plugin and are co-installed. If /skill-audit is unavailable, stop and ask the
user to install the kyberforge plugin before continuing.
Package-intent gate
Judge whether the destination is meant to be inside an APM package before running the scaffold script — the script cannot tell "no package here" apart from "package not scaffolded yet":
- Package intent but no
type:-bearingapm.ymlfound at or above the destination (e.g. "add to my apm package", or a sibling.apm//apm.ymlexists nearby) → stop, tell the user to run/apm-workflow configure(apm plugin init, from inside the package directory) first, then retry. Do not fall through to standalone mode. - Otherwise (a
~/-rooted destination, or no package context implied) → continue to Step 1.
Step 1 — Scaffold
Run the copy script with the skill name and a path inside or at the target:
bash scripts/new-skill.sh <skill-name> <path>
The script walks up from <path> for a package boundary: an ancestor apm.yml with a top-level
type: field (instructions/skill/hybrid/prompts) means package mode — scaffolds into
<package-root>/.apm/skills/<skill-name>/, not under <path> (a subdirectory of the package
works fine as <path>). A type:-less apm.yml is a marketplace-only manifest, skipped. Hitting
.git or the filesystem root first means standalone mode — scaffolds directly into
<path>/<skill-name>/.
Examples:
# Package mode — packages/my-pkg/apm.yml already has `type: skill`
bash scripts/new-skill.sh my-tool packages/my-pkg/
# Standalone mode — no apm.yml/.git above ~/.agents/skills/
bash scripts/new-skill.sh my-tool ~/.agents/skills/
The script prints which mode it used and where the skill landed — read its output.
In package mode, read references/deployment-modes.md before adding any file references to
SKILL.md.
Step 2 — Update apm.yml includes (package mode only)
Skip in standalone mode. In package mode, check the resolved package's apm.yml: if includes:
is an explicit list (not auto), append .apm/skills/<skill-name>/ to it if not already present,
preserving YAML formatting. If includes: auto or the field is absent, do nothing — auto
already covers the new skill. Use Read/Edit directly on apm.yml; this is not part of
scripts/new-skill.sh.
Step 3 — Fill in SKILL.md
Open the new skill's SKILL.md (the path Step 1 printed) and replace every FILL IN:
placeholder. The scaffold template already carries the compliant frontmatter and body skeleton —
fill it rather than restructuring it.
name — already set by the scaffold script. Must exactly match the directory name. Format:
1–64 characters, lowercase letters, numbers and hyphens only; no leading, trailing or consecutive
hyphens (--).
description — carries the entire triggering burden and is preloaded every session. Write it
against references/contract.md, which holds the three-part shape, the banned content, the
boundary-clause form and the length tiers. A hand-invoked skill (SKILL.md Step 2) takes one
plain sentence and disable-model-invocation: true instead.
Optional frontmatter — uncomment and fill in, or remove entirely:
license— include when distributing the skill externallycompatibility— include if the skill requires specific tools, runtimes, or network access (max 500 characters)metadata— key-value map; useauthor,version,category; addsource_keysnow (Step 6) if research sources are in contextallowed-tools— space-separated pre-approved tools; reduces permission prompts (experimental — support varies by client)disable-model-invocation— hand-invoked skills only
metadata.source_keys — if research sources are in context, list the relevant slugs as you
write the body; do not defer this to Step 6. Agents that fill in source_keys late tend to omit
it entirely. Example:
metadata:
source_keys:
- my-source-slug
- another-slug
Body — write the decision procedure only, following the body rules and patterns in
references/contract.md. Rename the placeholder section headings to ones that fit the skill's
structure.
Step 4 — Add scripts (if needed)
Place executable scripts in scripts/. Critical rule: no interactive prompts — agents run
non-interactive, and blocking on TTY input hangs indefinitely. Accept all input via flags, env
vars, or stdin.
If adding a script, read references/scripts.md first — it covers the full contract: structured
output, pinned versions, self-contained deps, idempotency, exit codes, dry-run, error messages,
and output size limits.
If no scripts are needed, delete scripts/README.md and the scripts/ directory.
Step 5 — Add references, assets, and tests (if needed)
references/ — additional documentation loaded on demand. One topic per file. Reference
conditionally from SKILL.md with the literal form If <condition>, read `references/<file>.md` .
Keep reference chains one level deep — a reference file that references another reference file is
rarely loaded correctly.
assets/ — static resources: templates, schemas, lookup tables. Reference by relative path
from SKILL.md.
tests/ — test files for scripts in scripts/. Use when scripts are complex enough to break
silently. Test infrastructure (.bats, *_test.*) belongs here, not in scripts/. See
tests/README.md for setup instructions.
If not needed, delete the placeholder READMEs and their directories.
Step 6 — Populate or delete references/sources.md
If a research sources.md is present in the conversation context:
- Read it and filter to entries with
`extracted`status only. - For each entry, determine which skill files it contributed to (SKILL.md and any files in
references/that drew from it). UpdateContributing filesaccordingly — list skill files, not research topic files. - Write the updated content to
references/sources.md. For each entry, include- **Research doc:** <path>where<path>is the relative path from the repo root to the plugin-level research sources file this entry was drawn from (e.g.plugins/myplugin/docs/research/docs/<topic>/sources.md). This field is required on every entry — it makes the provenance chain explicit and is validated by/skill-audit. - Add
source_keysto the frontmatter ofSKILL.md(undermetadata) listing the slugs of sources that informed it. - For each file in
references/that was informed by research sources, addsource_keysfrontmatter (same format as research topic files) listing the relevant slugs.
If no research sources.md is in context, delete references/sources.md.
Then return to SKILL.md Step 4.