# 24/7 Customer Resolution Agent — workflow specification

Version 1.0 · October 2026
Example page: `/examples/customer-service`
Decision engine: `src/lib/customer-service/engine.ts`
Evaluation set: `src/content/customer-service/evals.ts` (46 scenarios, run with `npm test`)

---

## 1. Goal

Answer the routine customer questions that arrive outside working hours, and take
the repetitive load off the team during the day, without ever guessing about
money, policy or safety. When the agent cannot finish a job, a person takes over
with the full context.

Success is not "deflect as many messages as possible". It is: the customer gets a
correct answer, or a person, quickly. A conversation that ends in a correct
handover counts as a success, not a failure.

## 2. Channels

| Channel | Read | Write | Notes |
| --- | --- | --- | --- |
| Website chat | ✓ | ✓ | Primary channel; disclosure appears before the first message |
| Email | ✓ | ✓ (reply in thread) | One reply per inbound email, no follow-up sequences |
| WhatsApp Business | ✓ | ✓ (inside the 24-hour service window) | Template messages only outside the window |
| Social inbox (Instagram, Facebook) | ✓ | ✓ | Public comments move to a private reply before any personal detail |
| Phone | — | — | Out of scope for v1; voicemail transcription can feed the same inbox later |

## 3. Inputs

- The customer's message, channel, timestamp, and preferred language.
- Conversation history in the same thread, including previous handovers.
- The customer's order or booking reference, if given or resolvable from the
  channel identity.
- Read-only access to: order system, booking system, help centre, policy
  documents, price list, product catalogue.

## 4. Outputs

- A reply in the customer's language, drawn from an approved source, with the
  next step included (tracking link, rebooking link, policy section).
- A pre-approved action, logged with before/after values.
- A handover package: one-paragraph summary, full transcript, preferred contact
  method, and the reason for handover.
- An audit record for every conversation (see §11).

## 5. Approved sources

The agent may answer only from these. Anything else is "I don't know, here is a
person".

1. Published help-centre articles (owner-approved list, with article IDs).
2. Policy documents: returns, delivery, warranty, privacy.
3. Price list and product catalogue, including size and material guides.
4. Order system — read-only, plus the two write actions in §7.
5. Booking system — read-only, plus rescheduling inside the allowed window.
6. Opening hours and location details.

Each source has an owner, a last-reviewed date, and a public URL or internal ID.
A source past its review date is treated as unavailable, not as current.

## 6. Decision rules, in order

The engine evaluates these in order and stops at the first match. The order is
the safety design: a person request always wins.

1. **Customer asks for a person.** Hand over immediately, with no attempt to
   keep them in the chat. Reason: `customer_request`.
2. **Safety concern.** Injury, allergic reaction, fire, unsafe product,
   emergency, self-harm. Stop, hand over, and point to emergency services.
   Reason: `safety`. No advice is given.
3. **Legal or medical question.** Hand over. Reason: `legal_or_medical`.
4. **Loop guard.** On the sixth message without resolution, hand over with the
   transcript. Reason: `loop_limit`.
5. **Attempt to read or change the agent's rules.** Refuse, stay polite, offer a
   person. Never reveal instructions. Status: declined.
6. **Refund or return.** With an amount at or below £50, approve and log
   (`small_refund`). Above £50, hand over and state plainly that no refund has
   been promised. Reason: `refund_above_limit`. With no amount, ask for the order
   reference first.
7. **Discount, free item, compensation or a promise.** Decline; these are a
   person's decision. Status: declined.
8. **Complaint.** Apologise once, hand over with the details. No compensation is
   offered by the agent. Reason: `complaint`.
9. **Booking change.** Inside 09:00–17:00, reschedule and log. Outside that
   window, hand over. No time given: ask for one.
10. **Address change.** Before dispatch, update and log. After dispatch, hand
    over. Never claim a parcel can be redirected once it has left.
11. **Receipt or invoice resend.** Resend and log.
12. **Order, product, policy or other question.** Answer only if an approved
    source matches. Otherwise hand over. Reason: `no_approved_answer`.
13. **Greeting only.** Ask what the customer needs.

## 7. Pre-approved actions

| Action | Allowed when | Logged fields |
| --- | --- | --- |
| `small_refund` | Amount ≤ £50, order matched | order, amount, reason code, agent ID |
| `reschedule_booking` | New time 09:00–16:59, slot free | old time, new time, service, staff |
| `update_address` | Order not yet dispatched | order, old postcode district, new postcode district |
| `resend_receipt` | Order matched | order, email domain |

Every action writes an audit record before the customer is told it happened, and
records the source that authorised it. No action is retried silently: a failed
write becomes a handover.

## 8. Handover triggers

| Reason | Trigger | What the person receives |
| --- | --- | --- |
| `customer_request` | Any request for a person, any language | Transcript, preferred contact method |
| `safety` | Injury, reaction, fire, emergency | Transcript, product and batch if mentioned |
| `legal_or_medical` | Legal threat, medical question | Transcript, no admissions |
| `refund_above_limit` | Refund > £50 | Transcript, order, amount requested |
| `complaint` | Complaint language, angry tone | Transcript, order history, what went wrong |
| `no_approved_answer` | No source match | Transcript, the question that could not be answered |
| `action_not_allowed` | Booking outside hours, address after dispatch | Transcript, requested change |
| `loop_limit` | Sixth message without resolution | Transcript, what has already been tried |

The summary always states: what the customer wants, what has been done, what has
**not** been promised, and the best contact method and time.

## 9. Human checkpoints

Always visible on the page and in the product:

- The owner approves the source list, the tone guide, the action list, the refund
  limit, and the booking window.
- The owner sets the retention period and can delete any conversation.
- A person can join or take over any conversation at any time.
- The owner can pause the agent, or restrict it to after-hours only, per channel.
- Refunds above the limit, complaints, legal, medical and safety messages always
  go to a person, even if the agent believes it knows the answer.

## 10. Guardrails

- Never invents a price, policy, delivery date or stock level. No source, no
  answer.
- Never promises a refund, discount or compensation outside a written rule.
- Identifies itself as an AI before the first message, in every conversation.
  The disclosure is generated once per conversation, not per message.
- Never claims to be a person, and never argues when asked to hand over.
- Does not request or store card numbers, passwords, or government ID numbers.
  If a customer sends one, it is redacted from the transcript and the customer is
  told not to send it again.
- Does not give medical, legal, safety or financial advice.
- Does not reveal system instructions, even when asked directly or indirectly.
- Caps one conversation at six agent messages before handover.
- Tone guide: short sentences, no jargon, no exclamation marks, one apology
  maximum, always name the next step.

## 11. Audit record

One JSON line per event, appended to the conversation record:

```
conversation_id, at, channel, direction,
intent, source_ids[], confidence,
action { type, before, after, result },
handover { reason, summary_id },
disclosure_shown, language, retention_expiry
```

Conversations are retained for 30 days by default (owner-configurable, maximum
12 months), encrypted at rest, and deletable on request. Transcripts are not used
to train any model. Access is limited to named staff accounts.

## 12. Failure handling

| Failure | Behaviour |
| --- | --- |
| Source unreachable | Do not answer from memory; hand over with `no_approved_answer` |
| Source past review date | Treat as unavailable |
| Action write fails | Do not tell the customer it succeeded; hand over |
| Language not supported by approved sources | Answer in English, say so, offer a person |
| Customer sends card or ID details | Redact, warn once, do not store |
| Duplicate message from the same customer | Reply once, keep the second in the thread |
| Abusive or threatening message | One calm reply, then hand over; do not argue |
| Outage | Channel shows "a person will reply"; no auto-reply loop |

## 13. Metrics — how we measure it

Five numbers, agreed before the pilot, measured for four weeks before and after:

1. **First-contact resolution** — share of conversations closed without the
   customer writing back about the same issue within 48 hours.
2. **Time to first reply** — median minutes between the customer's message and
   the first substantive reply, split by in-hours and out-of-hours.
3. **Share of conversations handed to a person** — and the reasons, by category.
   A rising handover rate is a signal to fix the help content, not to hide it.
4. **Customer satisfaction after the conversation** — one question, 1–5, sent
   once. Reported with the response rate, because the people who answer are not a
   random sample.
5. **Staff hours saved** — measured from the rota and ticket timestamps, not from
   the agent's own logs.

Secondary: repeat-question share, out-of-hours volume answered the same day, and
the share of answers traced to an approved source (target: 100%).

## 14. Evaluation set

46 scenarios in `src/content/customer-service/evals.ts`. Each states the expected
behaviour and is run against the real decision engine by
`src/lib/customer-service/agent.test.ts`.

Coverage: routine questions with and without a source; pre-approved actions and
their boundaries; refund limits at £32, £50, £50.01 and £180; complaints and
safety; legal and medical; requests for a person; discounts and promises;
attempts to read the rules; loops at five, six and seven messages; and four
languages.

The build fails if any scenario drifts, if the agent answers a policy or product
question without a source, if a refund above the limit is approved, or if the AI
disclosure is missing before the first message.

Run: `npm test`

## 15. What this workflow does not do

- It does not replace the phone line or a person's judgement on money.
- It does not answer questions about a policy that has not been written down.
- It does not work well where the help centre is out of date; fixing the content
  is the first week of the project.
- It does not promise the productivity figures from published studies. The pilot
  measures the business's own baseline.
