> ## Documentation Index
> Fetch the complete documentation index at: https://maestro.rasa.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Sub-skills & Composition

> Compose small focused skills into larger conversational flows.

When a skill needs another skill's logic mid-conversation, it references it with `@skill.<name>`. The parent stays on the stack, the sub-skill runs, and the parent resumes with the sub-skill's public memory available to it.

## The `@skill.<name>` reference

```markdown theme={null}
Help the customer replace a credit card.

First, verify their identity: @skill.authentication

Once authenticated, check eligibility and help them choose a card.
```

When the orchestrator reaches `@skill.authentication`, it parks Card Replace on the stack, runs Authentication to completion, then resumes Card Replace, which can now read Authentication's public fields such as `authenticated` and `party_id`.

Write `@skill.<name>` when the parent needs another skill's result to carry on.
A customer who changes topic mid-conversation is handled by the engine on its
own, with no authoring needed. For how each case parks and resumes the parent,
see [Jumps to blocks and skills](/docs/maestro/reference/skill-md#jumps-to-blocks-and-skills).

## Composition rules

1. **Default to small, focused skills.** Each skill does one thing and exports results as public memory. Transaction lookup is its own skill, not embedded in disputes, refunds, and fraud review.
2. **Compose when you need context continuity.** A dispute skill calls transaction-lookup as a sub-skill. The parent owns the conversation.
3. **The parent must have meaningful business logic of its own.** If you strip out all the `@skill.<name>` references and the skill is empty, it's not a skill. That's the orchestrator's job.

## Depending on another skill's outcome

A skill can declare its own `requires:`, and the orchestrator offers it only
once that condition holds:

```markdown skills/card_replace/skill.md theme={null}
---
name: Card Replace
description: Replace a credit card -- lost, stolen, damaged, or not received
requires: "session.project.authenticated"
---

Help the customer replace a credit card.
```

This is the loosest way to compose. Card Replace depends on whatever skill sets
`authenticated`, never on the authentication skill itself. The memory key is the
whole contract, which is why it lives in the project-level `memory.yml` rather
than inside either skill.

Reach for this when one skill simply must not start before another has done its
job, and for `@skill.<name>` when the parent needs the result mid-conversation.

## Which one to use

| Write...            | For...                                 | Because invoking it...                   |
| ------------------- | -------------------------------------- | ---------------------------------------- |
| `@block.<block_id>` | An **ordered block** within this skill | Runs in **this** skill's context         |
| `@skill.<skill_id>` | Another **skill**                      | Opens a **separate** context and returns |

Both take the *id*, not the display name: `@skill.card_disambiguation` for a
skill in `skills/card_disambiguation/`, and `@block.pick_card` for a block
declared as `:::ordered_block id=pick_card`.

Tools need no token. They are already in the model's schema while their skill is
active, so name them in plain prose.
