Skip to content

docs: document what qualifies as a skill - #92

Closed
MajorLift wants to merge 1 commit into
mainfrom
jongsun/docs/skill-admission-criteria
Closed

docs: document what qualifies as a skill#92
MajorLift wants to merge 1 commit into
mainfrom
jongsun/docs/skill-admission-criteria

Conversation

@MajorLift

@MajorLift MajorLift commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds two admission questions to CONTRIBUTING.md that review currently answers ad hoc, and that no automated check can answer. Adapted from the ADR 0057 review, where acceptance criteria were raised as an open item.

Is it a skill, or does it belong in an enforcement layer?

Skills shape generation. Linters, hooks, and fitness functions enforce. Both should exist for any pattern load-bearing enough to encode — the section adds a table of the four layers and where each sits.

Three ways a proposal fails:

  • Substitutes for enforcement → unsafe. An agent can ignore any context it is given, so anything that must not be bypassed belongs in a hook or lint rule.
  • Restates a deterministic check → wasteful. Spends context on every invocation to duplicate ground truth CI produces for free.
  • Teaches the upstream pattern so enforcement rarely fires → the right shape. An existing lint rule is evidence the pattern matters enough to encode at both layers; the skill should name the layer it pairs with.

The review question becomes "is this doing generation-time work the linter cannot?" rather than "is this redundant with the linter?"

Does it earn its context budget?

Frontmatter for every installed skill loads at agent startup, as fixed overhead growing linearly with the catalogue — a skill that is never selected still costs its description on every run. Criteria: not a duplicate, actionable rather than aspirational, scoped so a reader can tell when it applies, description within the documented budget.

Notes

  • Docs only, no behavior change, no CHANGELOG.md entry.
  • The section closes by pointing structure and schema checks at yarn test, so review attention goes to the two questions no check can answer.

Two admission questions that review currently answers ad hoc, and that no
automated check can answer.

The first is whether the thing is a skill at all. Skills shape generation;
linters, hooks, and fitness functions enforce. A skill that substitutes for
enforcement is unsafe, because an agent can ignore any context it is given. One
that restates what a deterministic check already verifies is wasteful, spending
context on every invocation to duplicate what CI produces for free. One that
teaches the upstream pattern so enforcement rarely fires is the right shape, and
should name the layer it pairs with.

The second is whether it earns its context budget. Frontmatter for every
installed skill loads at agent startup, so a skill that is never selected still
costs its description on every run.

Adapted from the review of ADR 0057 (MetaMask/decisions#162).
@MajorLift MajorLift closed this Jul 30, 2026
MajorLift added a commit that referenced this pull request Jul 31, 2026
## Summary

Acceptance criteria for skill contributions, in both halves — a CI
validator for the deterministic properties, and the two questions in
`CONTRIBUTING.md` that no check can answer. From the [ADR 0057
review](MetaMask/decisions#162), where
acceptance criteria were raised as an open item.

## The validator

`yarn lint:skills` checks directory layout, `skill.md` path and name
pattern, frontmatter keys and maturity values, `mms-` prefix misuse,
repo-overlay names, and description length. `tools/skill-schema.mjs` is
the single source of truth, imported by the linter so the documented and
enforced schemas cannot drift.

**Description budget is 1,536** — a repo budget, not an operator limit.

An earlier draft used 1,024, justified as the per-operator minimum
citing OpenCode. That does not hold up: `tools/install` emits the
description verbatim with no truncation anywhere in the tooling, and six
skills over 1,024 — up to 1,344 — install and load in Claude Code today.
It also never bound anything, since the 46 skills on `main` have a
median description of 45 characters and a maximum of 928.

Enforcing it had a real cost. A description is the discovery surface and
the only part of a skill carrying its own trigger cues, so trimming one
to fit makes the skill less likely to be selected when it is relevant.
The budget still exists — always-on context should be bounded — but at a
number that reflects a deliberate choice rather than an unverified
external claim, and the comment now asks for an operator and version
before anyone tightens it.

## What running it against `main` turned up

Three errors, two of which were defects in the repo rather than in the
check:

- **`workflows/` never shipped.** 14 files across two `web3-tools`
skills, referenced **22 times** from their bodies, absent from the
installer's bundle list — so every installed copy carried 22 dangling
links and nothing reported it. Added to `copy_bundle_dirs`; all 22 now
resolve, 42 files delivered.

This is the third instance of one root cause, after `pr-validate`'s
`hooks/` and domain `knowledge/`: a directory that exists in source and
is not in the copy list.

- **`metadata` was rejected** as unknown frontmatter, though README
documents it as preserved through install. Now in the optional set.

- **`performance` description was 1,078 chars.** Under the 1,536 budget,
so it stays as authored — an earlier trim to 928 was reverted along with
the ceiling that motivated it.

Validator now reports **0 errors across 46 skills**.

## So the list stops being written twice

Two tests read `tools/install` directly:

- `BUNDLE_DIRS` must match the directories it copies.
- Every key it reads via `frontmatter_value` must be declared in the
schema.

The comment asking a human to keep Bash and JS in sync is now checked.
Knowledge files also get their own declared keys, since they take
`domain` rather than the installer-behaviour keys skills use.

## And the half a linter cannot check

`CONTRIBUTING.md` gains two questions:

**Is it a skill, or does it belong in an enforcement layer?** Skills
shape generation; linters, hooks, and fitness functions enforce. A skill
that *substitutes* for enforcement is unsafe — an agent can ignore any
context it is given. One that *restates* a deterministic check is
wasteful. One that *teaches the upstream pattern* so enforcement rarely
fires is the right shape, and should name the layer it pairs with.

**Does it earn its context budget?** Frontmatter for every installed
skill loads at agent startup, so a skill that is never selected still
costs its `description` on every run.

## Keeping the number honest

Two tests, because the failure mode here was documentation drifting from
enforcement in both directions:

- The boundary case derives its length from `DESCRIPTION_MAX` rather
than hardcoding one, so it keeps testing the boundary when the budget
moves. The previous hardcoded 1,100 silently stopped exercising anything
the moment the ceiling rose.
- A new check fails if `README.md`, `CONTRIBUTING.md`, or
`.github/SKILL_TEMPLATE.md` state a figure the schema does not enforce.
All three had said 1,536 while the schema said 1,024; reconciling them
by editing the docs down was the wrong direction, and this makes that
disagreement fail rather than get silently resolved.

## Test plan

- [x] `node .github/scripts/lint-skill-entry.mjs` — 0 errors, 46 skills
- [x] `test/lint-skill-entry.test.mjs` — 10 pass, including both drift
checks
- [x] `test/cli.test.mjs` 11 pass, `test/unit.test.mjs` 30 pass
- [x] Real install of `web3-tools`: 22/22 `workflows/` references
resolve, 42 files delivered
- [x] 84 remaining warnings are all missing recommended sections —
advisory, non-blocking

## Notes

- Supersedes #92, folded here: the check handles what it can, the prose
says where to spend review attention instead.
- 84 warnings suggest either the recommended sections are wrong for this
corpus or most skills predate them. Worth a follow-up decision; not
blocking, since warnings do not fail CI.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant