Goal
Add flight_status where get_flight_status is invisible until booking_ref is in memory.
Teach
At the prose-only stage, the LLM can call tools too early. Progressive control turns that into a runtime guarantee:
tool_constraints:
- get_flight_status:
requires: session.flight_status.booking_ref
requires is a condition expression, and every memory reference in one is fully namespaced as session.<scope>.<field>. The scope is a skill id, project for fields shared across skills, or system. So session.flight_status.booking_ref means “the booking_ref field belonging to the flight_status skill”.
Until that field has a value, the tool is removed from the schema entirely. The model cannot call a tool it never sees.
This is the first hard lever. The instruction body can stay almost unchanged.
Paste
Paste set: tutorial/snippets/step-03-constraints/
Copy into skills/flight_status/.
Also declare the memory field the constraint reads:
# skills/flight_status/memory.yml
schema:
public:
booking_ref:
type: text
description: Horizon Travel booking reference such as HT12345.
llm_settable: true
Three details that are easy to get wrong: the root key is schema, the text type is called text (not string), and llm_settable: true is what allows the model to fill the field from what the traveler says.
Train and try
make train
make inspect
Try: “Is my flight on time?” without a booking reference — Atlas should ask for it first.
Then: “Booking H T one two three four five — is my Lisbon flight delayed?”
Verify: Status for HT12345 returns (outbound is delayed 45 minutes in the demo data).
Talking point
Soft instructions become guarantees by adding frontmatter — not by rewriting the whole prompt.
