Skill Publish
Place a standard skill package into this shared skill home, activate it explicitly, keep the README in lockstep, and
verify binding. This skill governs placement + registration inside the home — it does not adopt a skill into
any project's toolset (that is the Skill Scout's pipeline and always needs user consent; skill_spec §6).
Registration is the precondition for everything downstream. The lifecycle is register → bind (+consent = adopt)
→ sync / contribute (see CONVENTIONS.md §0): a skill that is not registered here is invisible to syncing-frameworks
(which compares released = registered + tagged versions) and to contributing-framework-changes (which PRs a registered skill).
This skill performs the register stage; binding and sync/contribute are downstream of it.
Model (read first)
- Activation is explicit.
skills/index.json is the single registration surface. Its normalized
<category>/<name>/SKILL.md path selects the category and package; a folder that is absent from the index is inert
and fails selfcheck. Repository placement metadata never enters model-visible frontmatter.
- Naming is gated, not assumed. A skill's
name/description must pass the naming-skills validator (the
authority for skill naming — name ≤64 / [a-z0-9-] / no edge hyphen / gerund / name==dir; description
non-empty / ≤1024 / what+when / keywords) before registration. This skill references that rule, it does not
restate it (consolidate-with-pointers); the gate runs at Step 0.5 and the whole-tree check at Step 5.
- Categories are agreed-and-created, not a fixed enum. Choose the functional category with the author. If
skills/<category>/ does not exist, create it and record the new category. The category set remains filesystem and
index data, never a hardcoded enum.
A category is a functional grouping (e.g. governance/ orchestration/ research/), not a framework repo.
- README is part of the deliverable. Every add / move / rename / remove updates the README (Skill-Catalog row +
category-layout line + Use-via-Prompt entry + keyword-triggers row where applicable). The README ⇄ skills consistency
is machine-checked by a multiset diff plus a catalog-row completeness check (Step 5), not a count compare — a
count compare misses a rename or a wrong-folder placement. (Catalog-row format:
CONVENTIONS.md §3.)
- Identity-decoupled. No org / account / project path is hardcoded. Targets are the local
skills/** tree; the
home repo is read from git remote get-url origin only if a remote reference is needed. Works for any consumer of
this home (skill_spec §9). See CONVENTIONS.md for the full home-local convention set.
- Regen is a build artifact. A consuming project regenerates each skill into
.claude/skills/<name>/ (gitignored).
Publishing a skill body obliges a byte-identical regen check (diff -r) wherever the home is consumed.
Triggers
- Manual / keyword: "发布一个 skill" / "publish a skill" / "把这个 skill 归类" / "categorize this skill" /
"add a skill to VEMO_SKILLS" / "新增 skill 到 skill 库".
- Not automatic — publishing is an authoring action, run on request.
Pre-Check (Step 0, mandatory)
- Confirm the working directory is a skill home (a
skills/ tree with a README.md, VERSION, CHANGELOG.md).
If not → "Not a skill home (no skills/ + README/VERSION/CHANGELOG)" → stop.
- Read the incoming skill's
SKILL.md frontmatter. If name: or description: is missing, or repository-only
category: is present, stop and normalize the source package first.
- Agree on the target functional category with the author. If the skill already exists under another category, treat
this as a move and confirm intent before relocating.
Step 0.5 — Naming gate (mandatory, before placement)
Run the naming-skills validator on the incoming SKILL.md (it is the authority for skill naming; this skill
references it, it does not restate the rules). Registration is blocked unless every hard rule passes:
name ≤ 64 chars, only [a-z0-9-], no leading/trailing hyphen, gerund (verb+ing) form, and
name == its parent directory name;
description non-empty, ≤ 1024 chars, states what-it-does + when-to-use, with trigger keywords.
Any hard FAIL (incl. a non-gerund name — a hard rule in this ecosystem) → report the failing rule, ask the author to
fix the name/description, stop. Body/length advisories are INFO and do not block.
Publish Flow
Step 1 — Resolve package identity and category
Read name: from SKILL.md; take category from the user's publishing decision or the existing indexed path.
Step 2 — Resolve the target folder
Target = skills/<category>/<name>/.
- If
skills/<category>/ exists → place into it.
- If
skills/<category>/ does not exist → create the folder (declare-and-create) and note "new category
<category> created" for the report and the CHANGELOG.
Step 3 — Place the body (and references)
Write SKILL.md and only necessary agents/, references/, scripts/, or assets/ resources under the target.
Generate/validate agents/openai.yaml. For a move, relocate the existing folder
(git mv skills/<old-cat>/<name> skills/<category>/<name>) so history is preserved — never copy-then-delete.
Add the normalized <category>/<name>/SKILL.md path to skills/index.json. This index mutation is the registration
event; keep paths unique, local, bounded, and deterministic.
Step 4 — Maintain the README (obligation)
Update README.md:
- Skill Catalog — add/update the skill's row: category (== indexed path category) · skill
(
`<category>/<name>` token, with <name> == frontmatter name:) · does · when to use · boundary.
(Catalog-row format: CONVENTIONS.md §3. The <category>/<name> token is what the Step 5 multiset diff extracts.)
- Layout section — ensure the
<category>/ line lists the skill (add the category line if the category is new).
- Use via Prompt — add a trigger entry + a Keyword-triggers sub-table row if the skill is user-prompt-triggered.
- R30: never hardcode a version number in the README — point at
VERSION + CHANGELOG.md.
(README entry-doc style: the R29+ entry-doc family in
skills/orchestration/publishing-deliverables/references/readme-style.md — incl. the bilingual pair.)
Step 5 — Self-check (machine, before declaring done)
- Three-way parity: README catalog tokens ==
skills/index.json references == filesystem
skills/*/*/SKILL.md. Report orphan rows, inert tree packages, dangling index references, and duplicates.
- Name ⇄ indexed path: frontmatter
name: equals the indexed <name> directory; category is path-derived.
- Identity grep-clean (skill_spec §9):
grep -Ei '<org>|<account>' on the new SKILL.md → 0 hits. (The home repo
name as an example is allowed only if annotated "resolved at runtime".)
- Naming conformance (whole tree) — run
naming-skills over every skills/*/*/SKILL.md and assert all
hard rules green (name ≤64 / [a-z0-9-] / no edge hyphen / gerund / name==dir; description non-empty / ≤1024 /
what+when / keywords). A FAIL here means a mis-named or stale skill slipped in — fix before declaring done.
- Skill-Catalog completeness (the row's quality; existence is already covered by the multiset diff above, so this
does not re-assert it). For each
skills/*/*/SKILL.md, in its Skill-Catalog row:
- derived-equality (deterministic): the row's category cell == indexed path category, and the skill
token's
<name> == frontmatter name:. (Equality, not just non-empty — the category column is the user-facing
"what category is this" answer; a non-empty-only check would let it drift and re-introduce the confusion this fixes.)
- curated non-empty: does / when to use / boundary cells are all non-empty.
- trigger coverage: every prompt-triggered skill has a row in the Use-via-Prompt Keyword-triggers sub-table.
Run on both
README.md and README_zh.md (R32 mirror). Any failure → fix before declaring done. (Format: CONVENTIONS.md §3.)
Step 6 — Regen + verify (where the home is consumed)
In a consuming project: regenerate the skill into .claude/skills/<name>/ and run
diff -r skills/<category>/<name> .claude/skills/<name> → must be clean (byte-identical; the copy is a build artifact).
Step 7 — Version + changelog + ledger
- Bump
VERSION (minor for a new skill / category; patch for a move or wording) and add a CHANGELOG.md entry
(name the skill, its category, and any new category created). Keep VERSION == CHANGELOG top == (at release) tag.
- PR-only + weekly train (ruled 2026-06-11): land the change via branch → PR → merge (no direct push to the
default branch). The tag + announcement are cut by the weekly Friday release train — PRs merged by the Friday
cutoff ride that train; unmerged PRs wait, and their contributions are not counted until merged.
- A publish is a workflow event — mirror it into the consuming project's
flow_log.md when run there.
Never touched
- A skill's adoption into a project toolset — that is the Skill Scout pipeline + a user-consent red line
(skill_spec §6). This skill places and registers; it never decides a skill is adopted.
- Instance files / runtime ledgers, except the
flow_log.md row recording a publish.
- The regenerated
.claude/skills/** copies as a source — they are build artifacts; the home skills/** is edited.
Notes
- Who runs it: the Skill Scout proposes a skill → the user consents → publishing places + registers it. The actor
is a role constraint, not a separate categorization system — agents are framework-homed (registry_spec), there is no
parallel agent-folder layout here.
- Difference from a flat skill dump: categorization is declared and machine-verified, so the home stays navigable
and the README cannot silently drift from the tree.
1---2name: publishing-skills3description: Publish a standard skill package into this shared skill home — agree on its functional category, place it under skills/{category}/{name}/, activate it in skills/index.json, then maintain the README and verify binding. Use when adding, moving, or renaming a skill in VEMO_SKILLS. Placement + registration only — adoption stays a user-consent decision.4---56# Skill Publish78Place a standard skill package into this shared skill home, activate it explicitly, keep the README in lockstep, and9verify binding. This skill governs **placement + registration** inside the home — it does **not** adopt a skill into10any project's toolset (that is the Skill Scout's pipeline and always needs user consent; skill_spec §6).1112**Registration is the precondition for everything downstream.** The lifecycle is **register → bind (+consent = adopt)13→ sync / contribute** (see `CONVENTIONS.md` §0): a skill that is not registered here is invisible to `syncing-frameworks`14(which compares released = registered + tagged versions) and to `contributing-framework-changes` (which PRs a registered skill).15This skill performs the *register* stage; binding and sync/contribute are downstream of it.1617## Model (read first)18- **Activation is explicit.** `skills/index.json` is the single registration surface. Its normalized19 `<category>/<name>/SKILL.md` path selects the category and package; a folder that is absent from the index is inert20 and fails selfcheck. Repository placement metadata never enters model-visible frontmatter.21- **Naming is gated, not assumed.** A skill's `name`/`description` must pass the **`naming-skills`** validator (the22 authority for skill naming — name ≤64 / `[a-z0-9-]` / no edge hyphen / **gerund** / name==dir; description23 non-empty / ≤1024 / what+when / keywords) **before** registration. This skill references that rule, it does not24 restate it (consolidate-with-pointers); the gate runs at Step 0.5 and the whole-tree check at Step 5.25- **Categories are agreed-and-created, not a fixed enum.** Choose the functional category with the author. If26 `skills/<category>/` does not exist, create it and record the new category. The category set remains filesystem and27 index data, never a hardcoded enum.28 A category is a **functional grouping** (e.g. `governance/ orchestration/ research/`), not a framework repo.29- **README is part of the deliverable.** Every add / move / rename / remove updates the README (**Skill-Catalog row** +30 category-layout line + Use-via-Prompt entry + keyword-triggers row where applicable). The README ⇄ skills consistency31 is **machine-checked** by a multiset diff **plus a catalog-row completeness check** (Step 5), not a count compare — a32 count compare misses a rename or a wrong-folder placement. (Catalog-row format: `CONVENTIONS.md` §3.)33- **Identity-decoupled.** No org / account / project path is hardcoded. Targets are the local `skills/**` tree; the34 home repo is read from `git remote get-url origin` only if a remote reference is needed. Works for any consumer of35 this home (skill_spec §9). See `CONVENTIONS.md` for the full home-local convention set.36- **Regen is a build artifact.** A consuming project regenerates each skill into `.claude/skills/<name>/` (gitignored).37 Publishing a skill body obliges a **byte-identical regen check** (`diff -r`) wherever the home is consumed.3839## Triggers40- **Manual / keyword**: "发布一个 skill" / "publish a skill" / "把这个 skill 归类" / "categorize this skill" /41 "add a skill to VEMO_SKILLS" / "新增 skill 到 skill 库".42- Not automatic — publishing is an authoring action, run on request.4344## Pre-Check (Step 0, mandatory)451. Confirm the working directory is a skill home (a `skills/` tree with a `README.md`, `VERSION`, `CHANGELOG.md`).46 If not → "Not a skill home (no skills/ + README/VERSION/CHANGELOG)" → **stop**.472. Read the incoming skill's `SKILL.md` frontmatter. If `name:` or `description:` is missing, or repository-only48 `category:` is present, stop and normalize the source package first.493. Agree on the target functional category with the author. If the skill already exists under another category, treat50 this as a move and confirm intent before relocating.5152## Step 0.5 — Naming gate (mandatory, before placement)53Run the **`naming-skills`** validator on the incoming `SKILL.md` (it is the authority for skill naming; this skill54references it, it does not restate the rules). Registration is **blocked** unless every **hard** rule passes:55- `name` ≤ 64 chars, only `[a-z0-9-]`, no leading/trailing hyphen, **gerund (verb+ing)** form, and56 `name` == its parent directory name;57- `description` non-empty, ≤ 1024 chars, states what-it-does + when-to-use, with trigger keywords.58Any hard FAIL (incl. a non-gerund name — a hard rule in this ecosystem) → report the failing rule, ask the author to59fix the name/description, **stop**. Body/length advisories are INFO and do not block.6061## Publish Flow62### Step 1 — Resolve package identity and category63Read `name:` from `SKILL.md`; take category from the user's publishing decision or the existing indexed path.6465### Step 2 — Resolve the target folder66Target = `skills/<category>/<name>/`.67- If `skills/<category>/` **exists** → place into it.68- If `skills/<category>/` **does not exist** → **create** the folder (declare-and-create) and note "new category69 `<category>` created" for the report and the CHANGELOG.7071### Step 3 — Place the body (and references)72Write `SKILL.md` and only necessary `agents/`, `references/`, `scripts/`, or `assets/` resources under the target.73Generate/validate `agents/openai.yaml`. For a **move**, relocate the existing folder74(`git mv skills/<old-cat>/<name> skills/<category>/<name>`) so history is preserved — never copy-then-delete.7576Add the normalized `<category>/<name>/SKILL.md` path to `skills/index.json`. This index mutation is the registration77event; keep paths unique, local, bounded, and deterministic.7879### Step 4 — Maintain the README (obligation)80Update `README.md`:81- **Skill Catalog** — add/update the skill's row: **category** (== indexed path category) · **skill**82 (`` `<category>/<name>` `` token, with `<name>` == frontmatter `name:`) · **does** · **when to use** · **boundary**.83 (Catalog-row format: `CONVENTIONS.md` §3. The `<category>/<name>` token is what the Step 5 multiset diff extracts.)84- **Layout section** — ensure the `<category>/` line lists the skill (add the category line if the category is new).85- **Use via Prompt** — add a trigger entry + a **Keyword-triggers sub-table** row **if** the skill is user-prompt-triggered.86- **R30**: never hardcode a version number in the README — point at `VERSION` + `CHANGELOG.md`.87(README entry-doc style: the R29+ entry-doc family in88`skills/orchestration/publishing-deliverables/references/readme-style.md` — incl. the bilingual pair.)8990### Step 5 — Self-check (machine, before declaring done)91- **Three-way parity**: README catalog tokens == `skills/index.json` references == filesystem92 `skills/*/*/SKILL.md`. Report orphan rows, inert tree packages, dangling index references, and duplicates.93- **Name ⇄ indexed path**: frontmatter `name:` equals the indexed `<name>` directory; category is path-derived.94- **Identity grep-clean** (skill_spec §9): `grep -Ei '<org>|<account>'` on the new `SKILL.md` → 0 hits. (The home repo95 name as an example is allowed only if annotated "resolved at runtime".)96- **Naming conformance (whole tree)** — run **`naming-skills`** over every `skills/*/*/SKILL.md` and assert all97 **hard** rules green (name ≤64 / `[a-z0-9-]` / no edge hyphen / gerund / name==dir; description non-empty / ≤1024 /98 what+when / keywords). A FAIL here means a mis-named or stale skill slipped in — fix before declaring done.99- **Skill-Catalog completeness** (the row's *quality*; existence is already covered by the multiset diff above, so this100 does not re-assert it). For each `skills/*/*/SKILL.md`, in its Skill-Catalog row:101 - **derived-equality** (deterministic): the row's **category** cell **== indexed path category**, and the **skill**102 token's `<name>` **== frontmatter `name:`**. (Equality, not just non-empty — the category column is the user-facing103 "what category is this" answer; a non-empty-only check would let it drift and re-introduce the confusion this fixes.)104 - **curated non-empty**: **does** / **when to use** / **boundary** cells are all non-empty.105 - **trigger coverage**: every **prompt-triggered** skill has a row in the Use-via-Prompt **Keyword-triggers** sub-table.106 Run on both `README.md` and `README_zh.md` (R32 mirror). Any failure → fix before declaring done. (Format: `CONVENTIONS.md` §3.)107108### Step 6 — Regen + verify (where the home is consumed)109In a consuming project: regenerate the skill into `.claude/skills/<name>/` and run110`diff -r skills/<category>/<name> .claude/skills/<name>` → must be clean (byte-identical; the copy is a build artifact).111112### Step 7 — Version + changelog + ledger113- Bump `VERSION` (minor for a new skill / category; patch for a move or wording) and add a `CHANGELOG.md` entry114 (name the skill, its category, and any new category created). Keep **VERSION == CHANGELOG top == (at release) tag**.115- **PR-only + weekly train (ruled 2026-06-11)**: land the change via **branch → PR → merge** (no direct push to the116 default branch). The **tag + announcement** are cut by the **weekly Friday release train** — PRs merged by the Friday117 cutoff ride that train; unmerged PRs wait, and their contributions are not counted until merged.118- A publish is a workflow event — mirror it into the consuming project's `flow_log.md` when run there.119120## Never touched121- A skill's **adoption** into a project toolset — that is the Skill Scout pipeline + a **user-consent red line**122 (skill_spec §6). This skill places and registers; it never decides a skill is adopted.123- Instance files / runtime ledgers, except the `flow_log.md` row recording a publish.124- The regenerated `.claude/skills/**` copies as a *source* — they are build artifacts; the home `skills/**` is edited.125126## Notes127- **Who runs it**: the Skill Scout proposes a skill → the user consents → publishing places + registers it. The actor128 is a role constraint, not a separate categorization system — agents are framework-homed (registry_spec), there is no129 parallel agent-folder layout here.130- **Difference from a flat skill dump**: categorization is declared and machine-verified, so the home stays navigable131 and the README cannot silently drift from the tree.