# A phone appointment is not a branch visit

Source: https://rasa.community/library/casebook/banking-advisor-appointment--conversation-designer/
Author: Rod Rivera
Published: 2026-09-18T09:00:00.000Z

A customer has chosen a phone appointment. Just before confirming, they ask to
come into a branch instead. The assistant replies, “Of course,” and books the
phone slot it already had.

The reply accepted the correction. The booking did not.

This is a fictional scheduling exercise at Northgate Bank. It starts with a
small design problem: how should the conversation change when the customer's
choice invalidates the appointment the system is about to reserve? You will
produce a revised confirmation, a state table and three replay tests that an
engineer can use to check the implementation.

## Start with the detail that changed

In this example, the customer wants help with online banking. The proposed
appointment is with a suitable support advisor by phone, on Tuesday at 10:00.
That is the offer on screen when the customer speaks:

> **Customer:** Actually, I need to come into a branch. It needs to be step-free.
>
> **Assistant:** I'll look for a step-free branch with someone who can help
> with online banking. The Tuesday phone appointment isn't booked. Do you want
> me to give up that phone slot while I look?
>
> **Customer:** Yes, I'd rather come in.

The second sentence is permissible only if the system knows that no booking has
been made. If a booking request has already been sent and its result is unknown,
the assistant needs the different response in the timeout section below.

Do not turn “step-free” into a request for the customer's medical history. It is
an appointment requirement. Nor should the assistant treat the nearest branch
as suitable merely because it has a free slot: advisor capability, access and
the customer's choice must all match.

For the exercise, assume the scheduling service can report whether a held slot
has been released. If your service cannot do that, the designer and scheduling
owner need to resolve that gap before promising the customer a replacement.

## Rewrite the confirmation from the new choice

A confirmation such as “Shall I book that?” leaves the customer guessing what
“that” refers to. Write it from the appointment record the booking tool will
receive. Here is the revised offer after the old hold has been released and a
suitable branch slot found:

> **Assistant:** The Market Street branch has step-free access and an online
> banking support advisor available on Wednesday at 11:30. Would you like that
> appointment?
>
> **Customer:** Yes, book Wednesday.
>
> **Assistant:** Your branch appointment is booked for Wednesday at 11:30.
> Your booking reference is NG-204. The Tuesday phone slot has been released.

Market Street and NG-204 are illustrative values, not results from a live
service. The last turn needs two separate observations: a receipt for the new
booking and confirmation that the earlier hold was released. If only one is
known, show only that part as complete.

The user has confirmed a particular purpose, channel, location and time. Changing
one of those details invalidates that confirmation. A previous “yes” to Tuesday
by phone cannot authorise Wednesday in a branch.

:::checkpoint{id="appointment-correction-confirmation" question="The customer agreed to Tuesday by phone, then asked for a branch visit. Can the assistant book the nearest available branch slot?" options="Use the earlier confirmation,Show the new appointment and ask for confirmation,Book if the advisor is qualified" answer="1"}
The changed offer needs its own confirmation. Advisor capability is necessary,
but it does not substitute for the customer's choice of place and time.
:::

## Give each waiting state its own message

Use this table as a handoff to engineering. It describes the information the
interface needs; it is not a claim that every scheduling API provides it.

| State                    | What the customer sees or can do                     | Evidence required to move on                                   |
| ------------------------ | ---------------------------------------------------- | -------------------------------------------------------------- |
| Phone slot offered       | Accept, change the appointment, or decline           | The exact purpose, channel and time shown in the offer         |
| Change requested         | Confirm giving up the phone slot, or keep it         | The customer's choice; no branch booking yet                   |
| Releasing the old hold   | Wait, ask for help, or stop searching                | The scheduling service reports the hold released               |
| Branch slot offered      | Check access, place and time; accept or change again | A matching advisor and a current slot hold                     |
| Booking submitted        | See that confirmation is pending; ask for help       | A booking receipt or an authoritative failure for this request |
| Branch booking confirmed | Read the details and reference                       | The receipt matches the newly confirmed appointment            |

There are two tempting shortcuts to reject during review. Keeping the phone
slot while announcing that the branch visit is booked can leave an unwanted hold.
Releasing it before asking the customer can take away an option they wanted to
keep. The dialogue above asks which tradeoff the customer wants, then makes the
chosen action visible.

If there is no suitable branch slot, offer a specific next step: keep searching
other dates, arrange a callback from the scheduling team, or stop. Do not quietly
replace the specialist with a general appointment. Ask the scheduling owner to
confirm who receives callback requests and what response time can be promised;
do not invent one in the script.

## When the booking response never arrives

A timeout after submission is a different state from a rejected booking. It does
not establish that the service did nothing. A useful message at this point is:

> **Assistant:** I haven't received confirmation of the Wednesday booking yet.
> I'll check the request already sent before trying again. You can wait here or
> ask the scheduling team to follow it up.

Engineering needs to retain the original request identifier and look up that
request. Sending a new identifier for the same booking can create a duplicate.
A customer's request to change the appointment again must not be squeezed into
that earlier identifier either: first establish what happened to the submitted
booking, then handle the change as a separate decision.

Agree one escalation rule for this exercise: if the first status lookup cannot
establish the outcome, stop automated booking retries and send the scheduling
team the request reference, the requested appointment and the unresolved status.
Tell the customer that follow-up has been requested only after the receiving
service acknowledges it. Avoid copying the entire conversation into that record.

## Use the small lab for the claim it actually tests

The [downloadable lab](/casebook/casebook.zip) contains a synthetic appointment
fixture. Extract it into a new folder and run this command from that folder
with Python 3.11 or later:

```bash
python3 casebook.py --case banking-advisor-appointment --prove
```

The result includes ten fixture observations and three removed-predicate tests.
For each of `purpose_matched`, `slot_held` and `channel_confirmed`, false,
missing and the string `"true"` must block the synthetic action. These checks
help explain why a conversational “yes” cannot fill in a missing service fact.
They do **not** test branch accessibility, slot release or the dialogue above.

You can also inspect the lost-response behaviour yourself. Use a fresh database
for these two commands so an earlier run does not become a replay:

```bash
python3 casebook.py --case banking-advisor-appointment --database appointment-demo.sqlite --request-id branch-1 --lose-ack
python3 casebook.py --case banking-advisor-appointment --database appointment-demo.sqlite --request-id branch-1 --lookup
```

The first result is `pending`, without a reference. The lookup returns
`succeeded`: the synthetic action had been stored even though its acknowledgement
was lost. This is the reason the waiting message cannot say “nothing was booked”.
There is no real bank, Rasa conversation or external scheduling integration in
this proof. Test the actual adapter separately before using the design in a
customer service.

## Rehearse the correction before approving the flow

Give a support colleague the dialogue prototype and these three tasks. Let them
use the available choices; do not explain the state table first.

1. Choose Tuesday by phone, then ask for a step-free branch visit. After the
   revised offer, ask which appointment is currently booked. The expected
   answer is neither: the branch visit still needs confirmation.
2. Confirm the branch visit, then withhold the booking response. Ask whether
   trying again is safe. The prototype must show that the original outcome is
   still being checked, and provide the scheduling-team route.
3. Ask for a branch visit when no suitable advisor is available. The colleague
   should be able to choose other dates, a callback or stopping, without being
   steered into a general appointment they did not request.

Record their answer at each transition alongside the prototype's displayed
state. Count each misunderstanding once per person per task; retain the number
of people who tried that task. These sessions reveal wording problems, not a
population-level success rate.

Do not approve the flow if a participant believes a pending appointment is
confirmed or cannot find the change and stop options. Revise that transition
and replay it. Then ask engineering to demonstrate the same sequence with the
real service: release the old hold, reject the old confirmation and inspect the
new booking receipt. The state table and those observations are the design
handoff; a friendly transcript alone is not enough.