Skip to content

tutorial

Chapter 8 of 10

Chapter 8 — Compose skills

by Rod Rivera Published

Build change_booking from authenticate and find_booking with @skill references and confirmation gates.

Goal

Compose small skills into a booking-change journey with authentication and confirmation.

Teach

When a skill needs another skill’s logic mid-conversation, reference it with @skill.<name>. The parent stays on the stack; the sub-skill runs and exports public memory; the parent resumes.

First verify identity: @skill.authenticate

Then find the booking: @skill.find_booking

Parent skills can also gate their own activation, using the same expression syntax at the top level of the frontmatter:

requires: session.project.authenticated

Mantle will not activate change_booking until that field is true — the only contract is the memory field.

Where shared fields live

This is the part that trips people up, so it is worth slowing down for. When a tool writes a memory field, the write lands in the namespace of the skill that is active at that moment. find_booking is the skill running when a booking gets selected, so if selected_booking_ref were declared inside find_booking/memory.yml, the value would land in session.find_booking.selected_booking_ref and change_booking could never gate on it.

Fields that travel between skills therefore belong in the project-wide memory.yml at the repo root, where they resolve to session.project.* no matter which skill is active:

# memory.yml (project root)
selected_booking_ref:
  type: text
  description: Booking reference the traveler has settled on for this request.
selected_trip_name:
  type: text
  description: Trip name for the selected booking.

A good rule of thumb: a field used by exactly one skill belongs to that skill, and a field that is a handoff between skills belongs to the project.

Confirming an irreversible tool

tool_constraints:
  - cancel_booking:
      requires: session.project.selected_booking_ref
      requires_confirmation:
        enabled: true
        utter_for_confirmation: utter_confirm_cancel_booking
        utter_on_user_denial: utter_cancel_aborted
      on_success: utter_booking_cancelled

Note the division of labour between the two gates. requires is a readiness check — it hides the tool until the data it needs exists. requires_confirmation is the human check — the tool is available, but the engine pauses and asks before running it. You rarely need a separate “did they confirm?” memory field, because the confirmation gate already is that check.

Composition rules:

  • Prefer small, focused skills that export shared state through project memory
  • The parent must have meaningful business logic of its own
  • @skill is coordinated; user interrupts are not guaranteed to resume the same way

Paste

Paste set: tutorial/snippets/step-06-composition/

Copy skills/authenticate, skills/find_booking, and skills/change_booking, plus the updated project memory.yml that adds the two shared booking fields.

Optional fast-forward for remaining skills: tutorial/snippets/step-07-remaining/ (human_handoff, goodbye, intro).

Demo PIN: four two four two (4242).

Train and try

make train
make inspect

Try: “I need to cancel a booking.”

Verify: Atlas authenticates, finds a booking, asks for confirmation, then cancels only after approval.

Talking point

Authentication is reusable across every sensitive skill. Transaction or booking lookup is reusable across changes, baggage, and status. Parents own the business outcome.

Next

Chapter 9 — Voice deep dive