# Extending a skill

> Add your team's rules to an rd-* skill at named extension points, without forking it.

Your rules do not replace ours. They are added at named places inside a
built-in, so you keep receiving updates to the skill and we never overwrite your
conventions. That is the whole idea; everything below is mechanism.

## What a wrapper is

An ordinary skill folder with one extra frontmatter field:

```markdown
---
name: team-build
description: Our extra rules on top of rd-build, for the payments repo.
extends: rd-build
---

Read rd-build first, then apply the sections below at their hooks.

## before-child

- Refuse to start a child on a dirty working tree.

## review-bar

- A child may not move to in review until a screenshot of every browse check is
  attached to its issue.
```

Save it at `.radial/skills/team-build/SKILL.md` to share it with the repo, or at
`~/.config/radial/skills/team-build/SKILL.md` to keep it to yourself.

Everything above the first `##` heading is the preamble: a standing instruction
for the whole run. Each `## <hook>` section is applied at the matching point in
the built-in.

## Build it in four steps

<steps>

<step title="Scaffold it">

```bash
radial skills extend rd-build --name team-build
```

You get the folder, the frontmatter, and one `## ` heading per extension point,
in the order they fire. Nobody has to memorise marker names.

</step>

<step title="Fill in the sections you want, delete the rest">

An empty section is noise in the agent's context. Two filled sections beat
eleven empty ones.

</step>

<step title="Make it invocable, if you want it by name">

```bash
radial skills install --project
```

That copies the repo's wrappers into `.claude/skills` and `.agents/skills`
alongside the pack, so `/team-build` works directly. Skip this and the wrapper
still applies: `rd-build` looks for it at the start of every run.

</step>

<step title="Check it fires">

Run the built-in and read the first few lines of the agent's output. A wrapper
that applied says so. If it did not, the symptom table below names why.

</step>

</steps>

## Why extension points are named, not numbered

A hook is a place in the procedure with a name and a job: `before-child` is
"before each child starts", `review-bar` is "the bar a child must clear to move
to in review". Because you attach to the name, we can rewrite the paragraph
underneath it and your rule still lands in the right place. A line number, or a
copy of the whole skill with your edits in it, would break the first time we
improved the sentence above yours.

Names ending in `-bar` are quality bars, and they are unique across the whole
pack: there is exactly one `review-bar`, so a rule you write for it means the
same thing in every repo you carry it to.

## What a wrapper can and cannot do

| Rule | Why |
| --- | --- |
| It adds rules and raises bars | An extension that could lower a bar would quietly disable the check that mattered |
| It cannot remove a step | The built-in is the contract; a team that wants a different contract wants a different skill |
| It cannot redirect output somewhere the built-in does not name | Otherwise reading the skill would stop telling you where your data goes |
| The nearest scope wins **whole**: project beats user, never merged | Two half-applied rule sets is the worst of both |
| Two wrappers in one scope extending one skill: neither applies | Silent precedence is worse than a loud refusal |
| `rd-*` names are reserved | So an update never fights your wrapper for a name |

When a section tries something it may not, the built-in follows its own
procedure and says so in its output. You find out in the run, not in a diff.

## Why isn't mine firing?

| What you see | Why |
| --- | --- |
| No mention of the wrapper at all | `extends` does not exactly match a skill name, or the file is not at `<dir>/SKILL.md` |
| The agent names two wrappers and applies neither | Two wrappers in one scope extend the same skill. Merge them, or move one to the other scope |
| Your user-scope wrapper stopped applying | A project wrapper appeared. Project scope wins whole, never merged |
| A section is ignored with a sentence about it | The heading is not one of that skill's hooks. `radial skills extend` scaffolds the valid ones |
| "not followed, and why" in the output | The section tried to remove a step or lower a bar |
| `radial skills install --project` refuses it | The name starts with `rd-`, or `extends` names a skill that is not in the pack |

## Where wrappers apply

The project scope (`.radial/skills/`) belongs in git. It is how a team's conventions
travel with the repo and get reviewed like anything else. User scope
(`~/.config/radial/skills/`) is for habits that are yours rather than the
team's.

A repo with no wrappers runs the built-ins exactly as published, which is the
right default and where everyone should start. Write a wrapper when you catch
yourself telling your agent the same thing twice.

<callout kind="tip">

`/rd-retro` phrases each of its proposals as a wrapper section you can paste
straight into a file. It is the cheapest way to get a first wrapper that is
about something that actually went wrong.

</callout>
