Skip to content
Back to skills

Moo Authoring

ASecurity

Use when adding or changing a skill, hook, or runtime file in this repo — including deciding which unit a new capability should be.

  • 34 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added August 31, 2026
ai-agentsgoapi

Works with

  • claude code
  • api

Security analysis

A100/100

Scanned September 29, 2026

npx -y skills add saadshahd/moo.md --skill moo-authoring --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Moo Authoring?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Moo Authoring
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/saadshahd-moo-authoring/badge)](https://www.skillsdirectory.com/skills/saadshahd-moo-authoring)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: moo-authoring
description: Use when adding or changing a skill, hook, or runtime file in this repo — including deciding which unit a new capability should be.
metadata:
  internal: true
---

Doctrine for authoring moo's own surfaces.

## Frontmatter

A skill's frontmatter carries `name` and `description`; read any shipped `SKILL.md` for the current key set. The description is one line, and Claude Code caps it at 1024 characters.

No `when_to_use`. Claude Code reads that key and renders it dash-joined onto the description, but every other agent copies `SKILL.md` verbatim and never reads it, so the text deciding when a skill fires would be invisible wherever it is installed outside Claude Code.

A condition that follows what the skill does is marked `Use when <condition>.` — a finite clause, never a bare noun phrase or a bare dash. The key name was what marked the condition as a condition; in one string nothing else does, and an unmarked trailing clause reads as more of what the skill produces. A description may also open with the condition and stop there, where naming the capability would discriminate nothing.

A skill that stays in this repo declares `metadata.internal: true`. The skills.sh installer walks the tree and offers every `SKILL.md` it finds; that flag is what it filters on.

Version lives in `plugin.json` only (DRY). The official Claude Code spec does not allow `version` in SKILL.md frontmatter.

## Sizing

- Size a skill by a deletion pass, never a numeric cap.
- Put branch-specific content in files the skill opens when the branch is taken, and name them where they are needed.
- Decision tables > prose explanations.

## Token Efficiency

- Challenge every sentence: "Does Claude need this?"
- Bullets for enumerable items; a paragraph when the point is one connected argument.
- No vague terminology; pick one term per concept.

## Skill Design

Phrase design decisions as "X over Y: reason".

**Unit choice** — behavior inlines at build, data references at runtime; a skill's firing is probabilistic, so behavior that must run every time is a hook:

| The new thing is... | Unit |
|---|---|
| Data selected per use (catalog, profile, corpus) | Runtime file |
| A trigger + procedure that stands alone | Skill |
| A trigger only the human perceives | Skill with `disable-model-invocation: true` |
| Behavior that must run every time, deterministically | Function hook |
| An unproven idea | hunch skill + `HYPOTHESIS.md`; graduates or dies |
| Doctrine for this repo's own surfaces | Repo-local skill in `.claude/skills/`; never ships |

**Composition — name-calls, never imports:**

- Skills compose by name: a composer names a move and invokes it with the Skill tool; a body never inlines another body.
- New skill when the cognitive mode changes (clarify WHAT ≠ decide HOW ≠ judge unsupervised work; find ≠ fix). One skill = one mode + one gate.
- Two skills over one when triggers differ; a shared explanation the pair needs lives in this file, which owns skill-design reasoning, not in either skill.
- A body names a sibling in exactly two places: a refusal, and a route — wherever in the body those sit. There the name *is* the refusal's or the route's content, and a reader without it is stranded.
- Ending over hand-off: a finished run states what is now settled and what is still open, in its own words. Naming who handles it next hardcodes the graph n², so one trigger change edits every sibling.

**Output form — bound by what the skill hands back, never by one shared sentence.** Plain words is the only part that holds across all three:

| The Output hands back | Bound it by |
|---|---|
| Something the agent restated in its own words | As short as it goes with nothing *the skill can't afford to drop* lost — name that thing, it differs per skill |
| The user's own words — a record, an amended proposal | Preserving them. A compression clause here destroys the result |
| A structure the reader navigates — verdict then evidence, a case set then a rule | Bounding each part where a reader would pad it, never the whole |

A cap counted in lines is a compression budget on a handed-back artifact — replace it. A cap on one turn of a loop is pacing, and the rest arrives on the user's next pull — keep it.

## Hook Design

Every hook is a function hook: it reaches the human with no model turn. The API is early access; `plugin-authoring` and `/plugin-types` are the reference for every event and call.

- A hook never starts a turn the human didn't ask for: no wake, no `$.prompt.submit` of its own.
- What a hook finds waits where the human looks next, the band above the prompt, and appears there only while it holds something. Detail unfolds on a press and folds back.
- A hook hands to Claude only on the human's Enter: `$.prompt.fill` a sentence start they finish, with any bulk added as `prompt.submit` context.
- Work longer than one dispatch runs unawaited, so the turn's end is never held.
- State lives in `$.state` (this session) or `$.store` (across sessions), never in temp files or module variables. A hot reload drops module variables.
- A failure shows once, as a toast, and the event passes on.
- A pane or band is verified on events copied from real session transcripts, one per shape it renders; a synthetic event alone never verifies it.
- One hooks module per plugin; a second part composes into it. A second registration on the same event and matcher in one plugin is dropped silently.

A hook that spawns headless `claude -p` copies its flag set from `hope/hooks/judge.sh`, where each flag is commented at the point of use.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.