docs: trim skill READMEs and ADR/changelog narration

Two related simplification-audit findings, bundled because they edit
some of the same skill-audit files and splitting would fragment
single-file diffs.

Finding 10: delete 48 per-skill/reference README.md files (they
restated SKILL.md in narrative form and no agent ever loads them) plus
2 scaffold templates. Drop the README criterion from skill-audit's
file-structure.md and finding-criteria.md, and the README-generation
step from skill-author's new-skill.sh; update new-skill.bats to match.
Plugin-root READMEs are kept intentionally, out of scope.

Finding 12: strip historical ADR-0020/ADR-0023 citations and
changelog-style narration from model-facing skill content across
kyberforge and git plugin skills. Delete skill-author's one-time
retrofit.md migration guide and its references. Some ADR-0023 tags
were not narration but check-rtk-prefix's required opt-out marker for
intentionally-bare git commands -- those were restored, not stripped.

Mirror re-synced and full pre-commit/pre-push suite verified green.

Refs: SIMPLIFICATION-AUDIT.md findings 10, 12

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
This commit is contained in:
2026-09-12 18:38:09 +00:00
parent 9eb8bc7e48
commit edcc57c0d6
167 changed files with 132 additions and 3897 deletions

View File

@@ -1,74 +0,0 @@
# skill-author
Author and refine skills conforming to the [agentskills.io](https://agentskills.io) specification — create new skills from scratch or apply improvement signals to existing ones.
## What it does
Routes to one of two flows based on context: if no skill directory exists at the target path, it scaffolds the directory from annotated templates, fills in `SKILL.md` and supporting files, and validates the result. If an existing skill directory and improvement signals are both present, it groups those signals by root cause and applies targeted edits, then re-validates. In both flows, bumps the skill's `metadata.version` — minor for create, patch for improve — which every skill carries (ADR-0022).
`SKILL.md` itself carries only the dispatch table, the invocation-axis decision, the contract gates and the shared close; each flow lives in its own self-contained reference file, per ADR-0020.
## The contract it teaches
Authored skills are held to the ADR-0020 context budget. A description carries a trigger clause, at most one capability clause, and a boundary clause of the form `Not <thing> -> <skill-name>` whose target must resolve to a real skill or agent — 250 characters target, 400 hard ceiling. A body carries the decision procedure only — 600 words target, 900 hard ceiling, counting the body alone, which is a separate measurement from the 2,770-word / 500-line whole-file spec backstop. Skills with two or more mutually exclusive flows must dispatch. `references/contract.md` holds the full rules; `assets/templates/SKILL.md` encodes them as a fill-in skeleton.
Before a description is written, the skill asks whether the target is model-invoked or hand-invoked. A hand-invoked skill sets `disable-model-invocation: true` and carries one plain human-facing sentence with no trigger list.
## Before you start
- Run `/grill-me` to resolve design decisions before creating a new skill
- Collect domain research, examples, and constraints
- Know the skill name (kebab-case) and destination path
## Placement
`scripts/new-skill.sh` resolves the mode automatically by walking up from the given path — see `references/create.md` Step 1 for the full algorithm.
| Mode | Path | Chosen when |
|------|------|-------------|
| Standalone | `<path>/<name>/` | No `apm.yml` with a top-level `type:` field is found walking up from `<path>`, before hitting `.git` or the filesystem root |
| Package (APM) | `<package-root>/.apm/skills/<name>/` | A type-bearing `apm.yml` is found at or above `<path>` — `<path>` just needs to be somewhere inside the package |
If the destination resolves inside an APM package, read `references/deployment-modes.md` — self-containment rules apply to `apm compile` output the same way they applied to plugin cache isolation.
## Usage
```
/skill-author
```
## Files
| File | Purpose |
|------|---------|
| `README.md` | Human-readable overview of the skill and its files |
| `SKILL.md` | Skill instructions for agents |
| `scripts/new-skill.sh` | Walks up from the given path to resolve package vs standalone mode, then copies annotated templates to the resolved destination |
| `references/create.md` | The create flow end to end — prerequisites, package-intent gate, scaffold, frontmatter, scripts, references, sources (loaded on demand) |
| `references/improve.md` | The improve flow end to end — signal verification, root-cause grouping, announcement, edits (loaded on demand) |
| `references/contract.md` | The ADR-0020 description and body contract, the Gotchas constraint, the two size gates, body patterns, and org-policy embedding (loaded on demand) |
| `references/retrofit.md` | Bringing a pre-ADR-0020 skill into contract — ordered cut procedure, the mutually-exclusive-flows test, reference-file conventions, the collateral checklist, and a worked description retrofit (loaded from the improve flow when a budget is exceeded) |
| `references/deployment-modes.md` | APM package vs standalone differences and self-containment/cache-isolation rules (loaded on demand) |
| `references/scripts.md` | Package runners, inline dependency patterns, and full script contract (loaded on demand) |
| `references/sources.md` | Upstream research sources and which skill files each contributed to |
| `assets/templates/SKILL.md` | Annotated SKILL.md template — emits an ADR-0020-compliant description and body skeleton |
| `assets/templates/README.md` | Annotated README template for the new skill |
| `assets/templates/scripts/README.md` | Placeholder for bundled scripts |
| `assets/templates/references/README.md` | Placeholder for reference docs |
| `assets/templates/references/sources.md` | Sources provenance template for new skills |
| `assets/templates/assets/README.md` | Placeholder for static assets |
| `assets/templates/tests/README.md` | Placeholder for test files |
| `tests/new-skill.bats` | (source-only) Bats test suite for `scripts/new-skill.sh` |
| `tests/README.md` | (source-only) Setup instructions for bats-support and bats-assert test dependencies |
Rows marked **(source-only)** exist in the authoring source (`.apm/skills/skill-author/`) but are
not present in an installed plugin: `scripts/sync-plugin-content.sh` strips
`<category>/<name>/tests` when it generates the flat mirror, because these are dev-time fixtures no
plugin host needs to discover (ADR-0017). Run them from a repo checkout, not from an install. The
`assets/templates/tests/README.md` row above is **not** source-only — the exclusion is depth-scoped
to `<category>/<name>/tests`, so the scaffolding template tree ships intact, which
`scripts/new-skill.sh` depends on at runtime.
## Spec reference
[agentskills.io specification](https://agentskills.io/specification.md)

View File

@@ -6,7 +6,7 @@ description: >
Not read-only review -> `skill-audit`. Not agent files -> `agent-author`.
allowed-tools: Bash Read Write Edit
metadata:
version: "1.0.1"
version: "1.0.2"
category: factory
source_keys:
- agentskills-home

View File

@@ -1,51 +0,0 @@
# SKILL_NAME
<!-- FILL IN: One sentence describing what this skill does. -->
## What it does
<!-- FILL IN: 2–4 sentences. What task does this skill handle?
What does the agent produce or accomplish when it runs? -->
## Before you start
<!-- FILL IN: List any prerequisites the user should have ready.
Examples: research docs, a grill session, specific input files, credentials.
Delete this section if the skill has no meaningful prerequisites. -->
## Usage
```
/SKILL_NAME
```
<!-- FILL IN: Add any required or common arguments.
If the skill takes no arguments, delete the code block above and just keep the slash command. -->
<!-- OPTIONAL: Manual (human) workflow — include if the skill bundles scripts a human can run directly.
**Manual workflow:**
```bash
# FILL IN: step-by-step commands
```
-->
## Files
<!-- FILL IN: List each file individually. Remove rows for directories you deleted.
Replace the example rows below with your actual files. -->
| File | Purpose |
|------|---------|
| `SKILL.md` | Skill instructions for agents |
| `scripts/your-script.sh` | FILL IN: what this script does |
| `references/your-doc.md` | FILL IN: what this reference covers |
| `assets/your-asset.json` | FILL IN: what this asset is |
| `tests/your-test.bats` | FILL IN: what this test covers |
<!-- OPTIONAL: Spec reference — include if this skill implements or follows an external standard.
## Spec reference
[FILL IN: Spec name](FILL IN: URL)
-->

View File

@@ -1,39 +0,0 @@
# references/
Additional documentation agents load on demand. Files here extend SKILL.md
without bloating its core context.
## When to add a reference file
The SKILL.md body carries the decision procedure only. Everything else lives
here: lookup tables, spec restatements, output schemas, templates, example
blocks, rationale prose, and anything only one branch reaches.
Two triggers make a reference file mandatory rather than optional:
- The body is over its 600-word target (900 is a hard failure), counting the
body only — everything after the frontmatter's closing `---`.
- The skill has two or more mutually exclusive flows. The body then keeps only
a dispatch table plus the gates common to every branch, and each flow gets
its own self-contained file here (e.g. `create.md`, `improve.md`).
## How to reference from SKILL.md
Load conditionally — tell the agent exactly when to read each file:
```markdown
If the API returns a non-200 status, read `references/api-errors.md`.
```
Avoid generic "see references/ for details" — the agent loads context on
demand, so give it a precise trigger condition.
## File conventions
- One topic per file — focused files mean less unnecessary context loaded
- Kebab-case filenames (e.g. `api-errors.md`, `output-formats.md`)
- Keep files under 200 lines where possible
## If no reference files are needed
Delete this README and the `references/` directory entirely.

View File

@@ -7,7 +7,7 @@ source_keys:
# The description and body contract
House contract, set by ADR-0020. Every rule here is enforced by `/skill-audit` —
House contract. Every rule here is enforced by `/skill-audit` —
`scripts/validate.sh` for the counts and the boundary targets, the bundled Vale styles for the
prose patterns, and its reference files for the judgment calls.

View File

@@ -84,7 +84,7 @@ already covers the new skill. Use Read/Edit directly on `apm.yml`; this is not p
## 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 carries the ADR-0020 body skeleton and the two frontmatter
placeholder. The scaffold template carries the body skeleton and the two frontmatter
fields that cannot be left as placeholders — `name`, substituted by the script, and
`metadata.version`, seeded live at `"0.1.0"` — so fill the template in rather than restructuring
it.

View File

@@ -71,23 +71,16 @@ outperforms an exhaustive one.
writing a rule in all caps (ALWAYS/NEVER), reframe it: explain why the behavior matters so the
agent can apply judgment in edge cases.
**Retrofit before extending.** Any edit to a skill that predates ADR-0020 has to bring it into the
contract first — the gates are hot and carry no baseline file, so a one-line fix to a
**Retrofit before extending.** Any edit to a skill that does not meet the contract has to bring it
into compliance first — the gates are hot and carry no baseline file, so a one-line fix to a
non-compliant skill cannot be committed until the description and body meet
`references/contract.md`. Treat that retrofit as part of the same change, not a follow-up.
If the skill's description exceeds 250 characters, or its body-only word count exceeds 600, read
`references/retrofit.md` before editing. It carries the ordered cut procedure, the
mutually-exclusive-flows test, the reference-file conventions this flow needs, the collateral
checklist for `README.md` and `references/sources.md`, and a worked description retrofit. Do not
improvise the cuts — four dry runs invented six to ten different answers to the same questions.
If a signal points to a script or reference file, edit that file directly rather than adding a
workaround in SKILL.md.
**A skill carrying no `metadata.version` is seeded at `"1.0.0"`, not bumped** — `SKILL.md` Step 4's
patch bump presumes a version to bump, and ADR-0022 reserves `"0.1.0"` for a newly created skill.
`references/retrofit.md` carries the reasoning.
**Check for regressions before handing back.** `SKILL.md` Step 4 tells you to resolve every FAIL,
which says nothing about a check that passed *before* these edits and no longer does. Compare the

View File

@@ -1,197 +0,0 @@
---
source_keys:
- agentskills-best-practices
- agentskills-optimizing-descriptions
---
# Retrofitting a skill to the ADR-0020 contract
Read this when `references/improve.md` Step 4 sends you here: the skill you are editing is over
the description or body budget and has to come into contract before any other change can be
committed. The gates are hot and carry no baseline file, so a one-line fix to a non-compliant
skill is blocked until this is done.
Measure first. Do not guess which gate fired: run `/skill-audit` on the directory and read its
`### Structure` dimension, which reports the description characters and the **body-only** word
count separately from the whole-file spec backstop. Retrofit against the number that actually
fired — a skill can sit a thousand words inside the whole-file backstop while failing the body
budget.
**Validate in place.** Audit the skill's real directory inside its package. Never audit a copy in a
scratch directory, and never move a skill out to work on it: the boundary-target universe is built
by walking up *from the file being checked*, so a copy with no authoring root above it resolves
against nothing and the check declines rather than running —
```text
INFO boundary-target resolution DID NOT RUN — no skill universe could be determined for
this path ... Unchecked target(s): totally-fake-target
```
The run still exits 0, so that line reads as a pass and is not one. Treat `DID NOT RUN` as **not
checked**, always. A retrofit signed off on a scratch copy carries an unverified boundary target
into the corpus, which is precisely the failure this gate exists to catch.
## Cut in this order
Work the list top down and stop as soon as the gate clears. The order is by ratio of tokens
removed to behaviour lost — inverting it is how a retrofit ends up deleting the one instruction
the skill existed to carry.
1. **Gotchas that paraphrase a step in the body below.** Zero information, and already a FAIL on
its own. Delete the Gotcha, keep the step.
2. **Spec restatements** — text that repeats a published specification, a tool's `--help`, or a
ceiling the validator already enforces. The agent gets this right without it. Delete, or move
the table to `references/` if a flow genuinely needs to look it up.
3. **Capability enumeration** — in a description, the feature list after the trigger clause; in a
body, the paragraph that recites what the skill can do. One capability clause survives in the
description; the rest belongs in `README.md`.
4. **Per-flow prose** — anything only one branch of the procedure ever reaches. This is the
largest single win in most bodies, and it is a *move*, not a delete: each flow gets its own
self-contained `references/` file, wired from a dispatch table.
If the body is still over after all four, the skill is doing two jobs. Split it, and say so
rather than compressing prose until it stops being readable.
## What "mutually exclusive flows" means
Two or more flows that a single invocation cannot both take. The three-way test, copied verbatim
from the body-discipline rubric `/skill-audit` judges against — nothing to load, it is quoted in
full here:
> separate subcommands, separate input types, separate lifecycle stages
Any one of the three is enough. Two flows that differ only in a parameter value are one flow.
At two or more mutually exclusive flows a dispatch table is **mandatory** regardless of word
count, because every invocation otherwise pays for every branch it did not take.
## Reference-file conventions
The create flow owns these rules, and this flow is forbidden from reading `references/create.md`,
so what a retrofit needs is restated here:
- **One topic per file.** A file mixing two concerns gets loaded for one of them and spends the
caller's context on the other.
- **Kebab-case filenames**, named after the topic rather than the flow that reads it —
`body-discipline.md`, not `step-3.md`.
- **Wire every file with the literal conditional form** ``If <condition>, read
`references/<file>.md` ``. A generic pointer ("see `references/` for details") is a Vale error.
- **Two hops from `SKILL.md`, never three.** A flow file may route on to a shared contract file;
a file reachable only through two intermediates is rarely loaded when it is needed.
- **`source_keys` frontmatter.** If the content you are moving drew on a research source, the new
file needs top-level `source_keys:` frontmatter listing those slugs, and every slug must already
exist as an `## <slug>` heading in `references/sources.md`. Moving sourced content out of
`SKILL.md` without carrying its slugs across breaks the provenance chain, and `/skill-audit`
reports the new file as an INFO with no `source_keys`.
## Collateral is mandatory, not optional
Moving content out of a `SKILL.md` leaves three files describing a structure that no longer
exists. `/skill-audit`'s provenance check exits clean on all three of these, so nothing catches
them for you. After every retrofit that adds, removes or renames a file:
- [ ] **`README.md` file table** — a row for every new `references/` file, and no row left for a
file that is gone. Say what triggers the load, not just what the file contains.
- [ ] **`references/README.md`**, where the skill has one — same update, same reason.
- [ ] **`references/sources.md` → `Contributing files`** — add the new file to every slug whose
content moved into it, and remove any file the retrofit deleted. This is the one that gets
missed: `sources.md` keeps citing sections of `SKILL.md` that no longer exist, the
provenance check still exits 0, and the stale claim survives review.
- [ ] **Reachability of every relocated gate.** For each Gotcha or gate the retrofit moved out of
the body, list the flows that need it and confirm each one reaches the surviving copy. A gate
that lands in a single flow file is invisible to every other branch, and no gate detects
that: `/skill-audit` reads whichever file it was handed, and the word counts improve either
way. Where more than one flow needs it, the copy belongs in the body's common-gates section,
not in a flow file. Grep the skill for the gate's key term and check every branch that hits
zero.
- [ ] Re-run `/skill-audit` and confirm its `### Provenance` dimension does not report the new
file as missing `source_keys`.
## Compression must not add authority the source text didn't have
This one is **not** part of the checklist above, and deliberately so: it fires on a wording change
with no file change at all, so a retrofit that adds and removes nothing still owes it.
The `sources.md` bullet above is about an entry going *stale* — Contributing files left uncited
after content moves. This is a distinct failure: a compression or rewrite pass that upgrades an
honest hedge in a Description into an unsupported confident claim, without the underlying source
having changed at all — "no forge-specific content drawn directly from it beyond that" quietly
becoming "Grounds Step 2's dispatch table."
`/skill-audit`'s provenance script does now notice this class: it diffs each slug's `Description`
and `Contributing files` text against a base ref and raises an **INFO** when the wording changed.
That is a prompt, not a verdict — it reports only *that* the claim moved, never whether the new
claim is true, because a bash script can verify an entry is internally consistent and nothing more.
Answering it is this flow's job: if a retrofit strengthens or otherwise changes the wording of a
provenance claim, re-read the upstream research doc first and confirm the stronger wording is
actually still true before committing it.
## Versioning a retrofitted skill
`SKILL.md` Step 4 says to bump the **patch** version on improve, which presumes there is a version
to bump. A pre-ADR-0020 skill often carries none — `metadata.version` only became mandatory under
ADR-0022, and this flow is exactly where those skills surface.
A skill with no `metadata.version` is **seeded at `"1.0.0"`, not bumped**. `"0.1.0"` is reserved
for a skill created new by the create flow: it means "created and never yet revised", which
understates a skill that has been through retrofit and audit passes without tracking a version.
Add the field in this retrofit — the `skill-frontmatter` pre-commit hook blocks the commit without
it.
## Worked example — a description retrofit
`gitea-issues` before, 827 characters, the single most common shape in the corpus:
```text
Use when reading or writing Gitea issues: listing repo issues, getting a single issue's details/
comments/labels, creating an issue, updating its state, adding or editing comments, applying
labels via issue_write, or searching issues/PRs across repositories. Triggers on "create an
issue", "what issues are open", "get issue #N", "close issue #N", "comment on issue #N", "search
issues for X" — even when the user doesn't say "Gitea" explicitly. Composes gitea-labels-
milestones for all label inference/resolution and milestone lookup — do not use this skill to
manage label or milestone definitions themselves (create/edit/delete a label, create/close a
milestone), that's gitea-labels-milestones directly. Do not use for pull requests (use gitea-prs)
or for local git branch/commit work (use gitea-branches or git-branches).
```
After, the 290 characters that shipped:
```text
Use when reading or writing Gitea issues — "create an issue", "what issues are open", "close
issue #N", "comment on issue #N", "search issues for X" — even when the user does not say
"Gitea". Not pull requests -> `gitea-prs`. Not label or milestone definitions ->
`gitea-labels-milestones`.
```
The retrofit kept the quoted-phrasing register and dropped the verb list, not the other way round.
Either register is admissible — what is banned is carrying both. Choose whichever routes better
for the skill in hand; here the quoted user phrasings do, because they are how people actually ask.
What came out, and why:
| Removed | Why |
|---|---|
| The second trigger register — `Triggers on "create an issue", "what issues are open", …` | The same triggers restated as quoted user phrasings. Two registers of one trigger list is a FAIL, not a suggestion. |
| `applying labels via issue_write` | Implementation detail. The router does not choose a skill by which MCP call it makes. |
| `Composes gitea-labels-milestones for all label inference/resolution and milestone lookup` | A composition note. It changes no routing decision and belongs in `README.md`. |
| The parenthetical `(create/edit/delete a label, create/close a milestone)` | Capability enumeration inside a boundary clause. The boundary needs the target, not its feature list. |
| The `gitea-branches` / `git-branches` boundary | Dropped entirely. Neither was ever going to win an issue request, so the clause defended against nothing — an invented boundary costs characters and buys no routing accuracy. |
| `Do not use for pull requests (use gitea-prs)` prose form | Kept, but rewritten as `Not pull requests -> \`gitea-prs\`.` The rewrite buys characters, one uniform shape for the router, **and** a stricter check: an unresolved arrow target is a blocking ERROR, while an unresolved prose target is only a SUGGESTION unless another target in the same sentence resolves. The prose form does not dangle as loudly. |
What stayed: one trigger clause, one capability clause, the indirect trigger (genuinely warranted
here — people say "create an issue", not "create a Gitea issue"), and the boundary clauses.
## Two rules the gates enforce but the prose does not spell out
**Boundary clauses may be plural.** Write one per genuine near-miss — the example above carries
two, because two different skills could each steal activations. "A boundary clause" in the
contract means *at least one*, not *exactly one*. What is banned is a boundary clause invented for
a skill that was never going to compete, not a second real one.
**Never let a hyphenated routing target wrap across lines in a folded `>` scalar.** YAML folding
replaces the newline with a space, so `gitea-labels-` at the end of one line and `milestones` at
the start of the next fold into `gitea-labels- milestones`. The gate then reads the target as
`gitea-labels`, finds no such skill, and reports a dangling boundary target. This is not
hypothetical — it is how `gitea-labels-milestones` broke (issue #100). It is fixed: the corpus
carries no dangling target today, and the repo's test suite pins that set as empty, so a
reintroduction fails the suite rather than joining a backlog. Reflow the line so the whole name
sits on one of them. The same applies to any backticked skill or agent name in a description.

View File

@@ -34,7 +34,7 @@ source_keys:
- **URL:** https://agentskills.io/skill-creation/best-practices.md
- **Research doc:** plugins/kyberforge/docs/research/docs/agentskillsio/sources.md
- **Description:** Best practices for skill creators — starting from real expertise, spending context wisely, calibrating control, instruction patterns (gotchas, templates, checklists, validation loops)
- **Contributing files:** SKILL.md, references/create.md, references/improve.md, references/contract.md, references/retrofit.md
- **Contributing files:** SKILL.md, references/create.md, references/improve.md, references/contract.md
- **Status:** `extracted`
## agentskills-optimizing-descriptions
@@ -42,7 +42,7 @@ source_keys:
- **URL:** https://agentskills.io/skill-creation/optimizing-descriptions.md
- **Research doc:** plugins/kyberforge/docs/research/docs/agentskillsio/sources.md
- **Description:** How to systematically test and improve skill descriptions for triggering accuracy — eval queries, trigger rate testing, train/validation splits, optimization loop
- **Contributing files:** SKILL.md, references/improve.md, references/contract.md, references/retrofit.md
- **Contributing files:** SKILL.md, references/improve.md, references/contract.md
- **Status:** `extracted`
## agentskills-evaluating-skills

View File

@@ -165,7 +165,6 @@ cp -r "$TEMPLATES_DIR" "$TARGET"
# Set skill name in templates
sed -i "s/SKILL_NAME/$SKILL_NAME/g" "$TARGET/SKILL.md"
sed -i "s/SKILL_NAME/$SKILL_NAME/g" "$TARGET/README.md"
sed -i "s/SKILL_NAME/$SKILL_NAME/g" "$TARGET/tests/README.md"
if [[ "$MODE" == "package" ]]; then

View File

@@ -34,11 +34,6 @@ teardown() {
assert [ -f "$DEST/my-tool/SKILL.md" ]
}
@test "scaffold contains README.md" {
bash "$SCRIPT" my-tool "$DEST"
assert [ -f "$DEST/my-tool/README.md" ]
}
@test "scaffold contains scripts/, references/, assets/, tests/ directories" {
bash "$SCRIPT" my-tool "$DEST"
assert [ -d "$DEST/my-tool/scripts" ]
@@ -53,12 +48,6 @@ teardown() {
assert_success
}
@test "substitutes skill name in README.md" {
bash "$SCRIPT" my-tool "$DEST"
run grep "my-tool" "$DEST/my-tool/README.md"
assert_success
}
@test "substitutes skill name in tests/README.md" {
bash "$SCRIPT" my-tool "$DEST"
run grep "my-tool" "$DEST/my-tool/tests/README.md"