Like-for-like: a line is shown only in the situation it was said in
Status: policy restructure done 2026-09-25 (policy/src/playbook-onboarding.json, policy/src/playbook-customer-success.json, regenerated policy/REDPEN.md). COPILOT-095 (2026-09-26) landed the data contract, the builder checks, the generated fits:: and situation:: questions, the red-pen sheet and the regenerated fixtures, and probed the questions live (§3.6). COPILOT-095b (2026-09-26) landed the engine gate (src/engine/situation.ts, plan.ts; §3.7). COPILOT-097 (2026-09-26) landed the slot requirements in the builder and the engine and gated where_is_my_money (§3.8); the live rendering is COPILOT-097b. Companion to docs/policy/rate-objections.md.
1. The rule
Stevan's rule: an approved playbook line may be suggested only when the client's actual question or situation matches the one the line was said in (harvested lines) or written for (drafted and PDF lines). Belonging to the same move is not enough.
The failure it prevents: customer success agree_next_step held two approved harvested lines, "You should be able to book the trade now." and "You should have the delivery date; just choose the next day that's available.", and the card could show the delivery-date line whenever the move was current, although the client's issue had nothing to do with delivery dates. The harvest shows what each line was actually said in:
| Line | What the client had just said (harvest, pseudonymised) |
|---|---|
agree_next_step.h1 "You should be able to book the trade now." |
"But what I'm gonna do now is just log on and then try to reset up the two factor authentication and do the trade that I wanted to do." (a login or two-factor block had just been fixed) |
agree_next_step.h2 "You should have the delivery date; just choose the next day that's available." |
"Oh, okay. Okay. So I have to request for Monday. Right?", "to be quick. Please remind me how does it start? That's in the website." (the client was on the booking screen, choosing a date) |
They are two different client situations. They are now two situations, and neither line can be shown unless its own situation fits.
2. What changed in the policy
Every approved line of both playbooks now sits under a situations[] entry of its own move, and so does every rate situation point. A move's flat lines[] keep only unapproved drafts (and the retired lines kept for the record). Nothing was renamed: every text_id is unchanged, and a moved line keeps every field it had (approved_by, approved_at, source, note, applies, locked).
| Onboarding | Customer success | |
|---|---|---|
| Situations | 24 (17 new, 7 rate) | 25 (18 new, 7 rate) |
| Approved situation points | 40 (21 moved lines, 19 rate points) | 45 (26 moved lines, 19 rate points) |
| Approved flat lines | 0 (was 21) | 0 (was 26) |
| Client examples | 60: 43 harvest, 11 drafted, 6 PDF | 57: 28 harvest, 23 drafted, 6 PDF |
2.1 Situation fields
| Field | Meaning |
|---|---|
id |
Unique in the playbook. The generated questions use it: fits::<id>, and an option of situation::<move>. |
headline |
The client's situation in their own words, 8 words or fewer, as approved text situation.<id>.headline (draft until Stevan red-pens it). |
what |
A literal description of when the situation applies, written for jev-1.13: the exact conditions in the client's (and where needed the rep's) turns, no inference about intent. It is the body of the fits:: noul and of the Choice option. |
not_for |
The nearest situations it must not fire in: the same move's other situations, the neighbouring move's, and Stevan's delivery-date case where it is the neighbour. It becomes the false criterion of fits:: and the option's not_for. |
client_examples |
[{text, source}], 2 or 3 client turns. harvest: a real, already pseudonymised client turn from data/analysis/harvest/turns.jsonl (verbatim substring). drafted: a plausible turn written for a drafted line (or where the harvest had no clean turn). ct-rate-objection.pdf: the playbook's own client line. They feed the red-pen and the L1 cases (COPILOT-096); they are never sent to Jev by the gate. |
applies |
Optional, the plan grammar (PlanApplies), inherited from the line (explain_who_holds_the_money.h2's partner gating) or from its placeholders ({country} lines only for a non-UK residency). Absent = always. |
hint |
Delivery guidance, approved text situation.<id>.hint (the builder requires one per situation; all new hints are drafts). |
qualify_first, core_text_id, points, do_not, do_not_flags |
As for the rate situations (COPILOT-083). New situations have qualify_first: false and no do-nots. |
Per point, two optional fields describe placeholders (COPILOT-097):
slot_requirements: [{placeholder, slot, leg?}]: code fills the placeholder from a client fact slot, and the point is shown only when that slot is known.slotis a fact slot id (residency,currency_pairwithlegsellorbuy) or one of two facts nothing can supply yet (settlement_partner,last_transfer_month), whose points therefore never show until a source exists.rep_fills: [token]: placeholders the rep fills from their own screen ([your name], the application's{currency pair}in the opener, the payee's name{payee}, which code must never fill from a transcript). Shown verbatim.
Every {…} or […] token of an approved point is covered by exactly one of the two; since COPILOT-097 buildPolicy refuses a bundle where it is not (§3.8).
2.2 How lines were grouped
The harvest decided it: for each harvested line, the client turn right before each rep turn in its cluster (turns.jsonl prev), or when that was only "Yeah." the nearest earlier client turn in the same call, and where a cluster's calls had no clean client turn, a matching turn from another harvested call. Lines whose client turns differ became separate situations; lines said in the same client situation stayed together as alternates (all shown, in order).
Split (one situation per client situation):
- CS
agree_next_step:ready_to_book_after_a_fix(h1) andchoosing_a_delivery_date(h2), Stevan's example. explain_who_holds_the_money:is_my_money_safe(h1, "is that FCA protected?") andwhere_do_i_send_funds(h2, "how does yours work, does it go into a different account?"), the second gated on the activating partner.confirm_funding_account:funding_owner_unclear(h2, "I can put it in my daughter's account") andbank_abroad_not_named(h1, "from Saudi Real into Sterling").close_the_document_gap:documents_outstanding_next_step(h2) andselfie_missing_or_rejected(h1).check_serviceability_first:works_abroad(h1) anduk_address_unclear(h2).ask_about_the_transfer:amount_not_said(h1) andfirst_transfer_date_not_said(h2).offer_alert_instead_of_waiting:waiting_for_a_better_rate(.1, h2, h1) andwaiting_but_has_a_date(.3).explain_document_request:which_statement_needed(h1) andinvoice_needed_for_payment(h2).review_upcoming_exposure:upcoming_payments_unknown(.1) andpayment_mentioned_no_amount(h1).offer_forward_for_known_future_payment:future_payment_rate_worry(.1) andputting_off_booking(h1).set_up_recurring_or_batch:same_payments_every_month(.1, .3) andseveral_payments_at_once(.2).add_user_access:someone_else_books_payments(h1, .1) andwants_a_second_approver(.2).
Kept together as alternates: pin_down_timing_and_amount h1 and h2 (both said after the client described plans without an amount); explain_booking_is_binding h1 and h2 (both said while walking the client through quoting and booking); the three status lines of give_status_with_specifics (one client question; which line is true depends on the trade status only the rep sees, so the hint says to read only the matching one); offer_alert_or_market_order h1, .1 and .3; reengage_dormant_with_a_reason .1 and .3; accept_no_need_gracefully .1 and .3.
The seven rate situations keep their points and headlines. Their what was rewritten as literal conditions (the fits:: noul reads it); the PDF's framing that was in what ("This is a reflex, not a demand …") moved to the situation's note, word for word.
One draft line was added with the restructure, set_up_recurring_or_batch.4 "Do you pay the same people every month, or several at once?", only because buildPolicy (assertPlanTemplates) and tests/unit/policy-src.test.ts then required a flat line per move. COPILOT-095 lets a situation point satisfy both and deleted it; the move now has no flat line.
2.3 Pseudonymisation
Harvest client examples are verbatim substrings of turns.jsonl, which the harvest had already pseudonymised ([NAME], [CLIENT], [COMPANY], numbers); drafted examples were written without any. None carries a person's name, a phone number, an email or an account number: every new string passed assertRedactedText (digit runs, IBAN, email, postcode) and the redactor's name pass (the only flags were sentence-initial words such as "Currently"). Call ids appear only in this document (§8 provenance), never in policy/src: a 10-digit id in a policy string would trip the fixtures' digit_run guard.
3. The gate (COPILOT-095)
3.1 The questions
Both are generated from the playbook like covered:: (COPILOT-089), not stored in shared.json. That was the brief's first option, and it was not taken, for three reasons: every bank question is sent on every full request today (there is no code gate, and question_groups live in rules-*.json), so a stored fits:: noul per situation (49 of them) would be asked on every decision until COPILOT-095 lands; tests/unit/policy-src.test.ts requires the bank ids and the rules-*.json signal ids to be the same set, so stored questions without signal entries fail it; and generating them from what/not_for keeps one copy of the wording, the way covered:: reads the point text. mergeBanks refuses bank ids starting with fits:: or situation::, as it refuses covered:: (COPILOT-095).
fits::<situation_id> (noul), one per candidate situation:
{
"type": "noul",
"instructions": "Does the client's latest turn, or a concern the client raised in `recent_transcript` that is still unanswered, match this situation? The situation: \"<what>\"",
"criteria": {
"true": "Every condition of the situation holds now, as shown by the turns in `recent_transcript`; the client's words, not the topic of the call, decide it.",
"false": "A condition does not hold, the client is talking about something else, or only a nearby situation is happening: <not_for>"
}
}
situation::<move> (Choice), only when the current item has two or more candidate situations:
{
"type": "choice",
"instructions": {
"question": "Which of these situations is the client in right now, judged from the client's latest turn and any concern the client raised in `recent_transcript` that is still unanswered? Choose `none` if none of them is happening.",
"focus": "Match the client's own words against each situation's `what`; respect each `not_for`. Belonging to the same topic is not enough."
},
"criteria": {
"<situation id>": { "what": "<what>", "not_for": "<not_for>" },
"none": { "what": "None of these situations is happening now: the client is on another topic, or has not said anything these describe." }
}
}
The rate items keep COPILOT-083's situation Choice, rate_objection_type in policy/src/shared.json. There is no per-move situation::<move> Choice in the code today; the rate Choice is the one 083 introduced, and it keeps its none option ("The client has not pushed back on the rate or price."), checked in shared.json on 2026-09-25. The generated situation::<move> Choice must always carry none as well: it is what lets the gate answer "no situation" instead of forcing the least bad one.
3.2 Which situations, and when
- Current item only. The candidates are the situations of the current plan item's move: a template item's
points.move, a client ask's move (ask:<move>), the move the engine picked for an inserted concern, or, for the rate-pressure item, the five client situations ofrate_objection_type(no_quote_in_hand,competitor_named,serial_shopper,mid_market_comparison,bank_matched).qualify_the_quoteandconcession_terms(the plan'srate_pressure.ask_first_situationandconcession_situation) are never candidates, even where a move reaches them throughsituation_refs(offer_forward_for_known_future_payment): they ride on the shown situation (qualify_first) and on the concession flag. appliesfirst. A situation whoseappliesdoes not hold is not a candidate (plan grammar; an unknown slot keeps it, an unknown fact does not, sowhere_do_i_send_fundsstays out untilsettlement_partner_knownexists).- At most 3
fits::per request (FITS_MAX = 3, likeCOVERED_MAX). All candidates when there are 3 or fewer (every non-rate move has 1 or 2); for the rate item, the episode's situation and the next two by the previous decision'srate_objection_typeprobabilities. - On client turns. The Choice and the
fits::nouls are asked on every client-turn decision while the item is current, and on the first decision after the current item changes (any speaker) so a new item is judged at once. On other rep-turn decisions they are not asked and the last answers hold: they judge the client's latest turn, which a rep turn does not change. - Re-typed rate episode (095b). When the rate episode is re-typed in place (bank matched after competitor named), the rate item is the same item, so its answers are kept, but the next decision asks again (any speaker) with the new situation first: its
fits::may not have been among the three asked before. - Concern items (095b). An inserted concern item's move is the card's move while that is on the concern's topic, else the first allowed move on it (as the item's points were chosen before 095b); it is fixed at the end of each decision, so the next request knows which
fits::to ask.
3.3 Thresholds and the decision rule
New policy thresholds in rules-*.json (hashed under weights_hash, so a change is absorbed by recompute): situation_fit: 0.6 and situation_min_conf: 0.4.
For the current item, on every decision, with C its candidates and f(S) the latest fits::S answer:
- One candidate S: show S when f(S) ≥ 0.60.
- Two or more: take the Choice's pick c (
situation::<move>, orrate_objection_typefor the rate item). Show c when c ≠none, its confidence ≥ 0.40 and f(c) ≥ 0.60. The two answers must agree; if the Choice picks one situation and a different one fits, nothing is shown. - Otherwise show nothing: the item keeps its title and shows "Listening", never a point. There is no fallback to the move's flat lines or to "the first situation with an approved point" for a move that has situations (
pointsOf's fallback stays only for a move without situations). - A shown situation shows its approved points in playbook order, minus any point whose
slot_requirementsare not all known (COPILOT-097). If that leaves none, it is "Listening" too. - Rate item: when the shown situation has
qualify_first, the "Ask first" block (qualify_the_quote) shows with it;concession_termsjoins while a price move is on the table (unchanged). If no rate situation fits, the item keeps its "Rate pressure" title and shows "Listening". covered::is asked only for the points on screen, anddeliveredcounts only points that were shown.
3.4 Budget
Measured with the policy-build worst case (a full 12-utterance window, every fact known, a concern open) on bundles built from the restructured sources:
| Request | Onboarding | Customer success |
|---|---|---|
Today's shape: bank + next_move + the 8 longest phrasing:: Choices (fixture-approved drafts) |
10,489 | 8,978 |
Same, plus 3 fits:: and one situation:: Choice |
11,742 (over the 11,000 soft budget) | 10,133 |
No phrasing:: Choice for a move with situations (every move now has them), plus 3 fits:: and one situation:: Choice |
10,210 | 8,804 |
One fits:: noul costs 246 to 292 tokens, one situation:: Choice 361 to 397. So COPILOT-095 must also drop phrasing:: for any move that has situations (its points come from the situation, as 083 already does for the rate moves). The code-rule drop order gains fits after all_phrasing and before window_to_8; a dropped fits:: is "unknown", which shows "Listening".
Measured in the engine (COPILOT-095b, tests/unit/policy-build.test.ts and tests/unit/engine-groups.test.ts, which now add the 3 longest fits:: nouls and the longest situation:: Choice of the fixture playbook to the worst case): onboarding 10,270, customer success 9,263 (policy-build) and 10,270 / 9,036 through planRequest (engine-groups), all ≤ 11,000 with nothing dropped.
With the rate group active the gate does not fit (open, §7 point 10). The worst case above has no rate-type concern open. With one open, the 16 rate questions join the request (COPILOT-081), and the fixture bundles measure (bank + next_move, state at the worst-case window):
| Request, rate concern open | Onboarding | Customer success |
|---|---|---|
| Window 12, no gate | 11,902 | 10,591 |
Window 12, + fits:: of the episode's situation only |
12,127 | 10,817 |
Window 12, + 3 fits:: (the rule above) |
12,602 | 11,292 |
Window 8, + 3 fits:: |
12,306 | 10,996 |
| One-utterance window, no gate | 11,419 | 10,272 |
Onboarding is over the soft budget with the rate group alone, even at a one-utterance window, so planRequest always drops the gate there (after all_phrasing, before window_to_8): the rate item keeps its title and shows "Listening" while any rate-type concern is open. In customer success the three fits:: push a 12-utterance request over soft, so the gate is dropped too; the episode's fits:: alone would stay. The unit tests of the rate item (tests/unit/engine-fit.test.ts (7), engine-rate.test.ts) put the gate's questions to the stub without the budget, as engine-rate already did for the rate group.
For comparison, the red-pen rounds alone (the committed sources before this restructure, fixtures regenerated) put the onboarding worst case over the soft budget: tests/unit/policy-build.test.ts and tests/unit/engine-groups.test.ts fail their ≤ 11,000 checks in that state. Moving the approved lines into situations removes the long phrasing:: Choices from real bundles and brings the budget back.
3.5 What the rep sees
| State | Current item shows |
|---|---|
| No candidate, or none fits | Item title and "Listening" |
| A situation fits (and, with two or more, the Choice agrees) | Item title, the situation's headline in quotes, its points ("Worth saying"), ticks as they are covered |
| It fits, but every point waits for an unknown slot | Item title, headline, "Listening" |
Rate item, situation fits, qualify_first |
"Rate pressure", headline, hint, "Ask first" block, then the points |
3.6 Live probe of the questions (COPILOT-095, 2026-09-26)
scripts/probe-questions.mjs --questions generates fits::<id> and situation::<move> from the draft playbook like covered:: (the situation:: Choice leaves out the rate helpers). Stevan's case, customer success, after the rep's "You should be able to see it on the dashboard now.":
$ node scripts/probe-questions.mjs --scenario customer_success --context rep:"You should be able to see it on the dashboard now." --latest client:"The payment to my supplier still hasn't arrived. Where is it?" --questions situation::agree_next_step,fits::choosing_a_delivery_date,fits::ready_to_book_after_a_fix
scenario: customer_success
planned: 3 ["situation::agree_next_step","fits::choosing_a_delivery_date","fits::ready_to_book_after_a_fix"]
estimate: 1418
model: jev-1.13.0
situation::agree_next_step: {"type":"choice","choice":"none","probabilities":{"none":1,"choosing_a_delivery_date":0,"ready_to_book_after_a_fix":0},"confidence":0.99}
fits::choosing_a_delivery_date: {"type":"noul","noul":0.03}
fits::ready_to_book_after_a_fix: {"type":"noul","noul":0.03}
usage: {"input_tokens":1255,"output_tokens":100}
usage.input_tokens: 1255 (estimate 1418)
The same with --latest client:"Delivery date. Does it make a difference?":
scenario: customer_success
planned: 3 ["situation::agree_next_step","fits::choosing_a_delivery_date","fits::ready_to_book_after_a_fix"]
estimate: 1406
model: jev-1.13.0
situation::agree_next_step: {"type":"choice","choice":"choosing_a_delivery_date","probabilities":{"none":0.02,"choosing_a_delivery_date":0.98,"ready_to_book_after_a_fix":0},"confidence":0.97}
fits::choosing_a_delivery_date: {"type":"noul","noul":0.87}
fits::ready_to_book_after_a_fix: {"type":"noul","noul":0.03}
usage: {"input_tokens":1245,"output_tokens":105}
usage.input_tokens: 1245 (estimate 1406)
Before the repair in §7 point 9, the second probe gave fits::choosing_a_delivery_date 0.33, 0.35 and 0.33 over three runs, with the Choice picking choosing_a_delivery_date at confidence 0.36 to 0.42: the old what asked for "booking a transfer on the platform during the call", which the turns never show. The first probe was unchanged by the repair (0.02 to 0.03 and none at 0.99, before and after).
3.7 In the engine (COPILOT-095b)
src/engine/situation.ts:fitsToAsk(s, u)(what the next request asks, read fromPlanMemory.fitonly),recordFits(the answers, instep()before the card and again inupdatePlan),retargetFit(same item keeps its answers; a new item, or a re-typed rate episode, is asked on the next decision),shownSituationId(the §3.3 rule),shownSituation(s, p)andpointsOf(move, shown, p).src/engine/plan.ts:candidateSituations(item, s, p); the view shows a situation's points on the current item only, withPlanItem.headline=situation.<id>.headlineandPlanItem.situation= its id (nullfor "Listening");deliveredcounts only covered points, which were all on screen when asked.src/engine/request.ts/budget.ts:assembleQuestions(…, covered, fits); thefitsdrop step (§3.4).src/jev/stub.ts:STUB_FITS(the five rules of the story,call_just_answeredfor the onboarding exemplars' first turns, and the five rate situations on the playbook's client lines) over the latest client turn.- Tests:
tests/unit/engine-fit.test.ts.
3.8 Slot requirements (COPILOT-097)
- Build (
src/policy/build.tsassertPointPlaceholders): every distinct{…}or[…]token of an approved situation point is covered exactly once, by aslot_requirements[].placeholderor arep_fillsentry, and nothing else is listed. A requirement'sslotiscurrency_pairorresidency(the slots with a typed param,POINT_PARAM_SLOTSinsrc/policy/fact-slots.ts) or one ofUNSOURCED_SLOTS = ['settlement_partner', 'last_transfer_month'];leg(sellorbuy) is given forcurrency_pairand only for it;residencyfills{country}only. A failure names the situation and the point. Everyfact_lists.countriesentry needs adisplayname ("Saudi Arabia"), the name COPILOT-097b renders for{country}instead of the chip label. - Engine (
src/engine/situation.tspointText, used byplan.ts): a point without requirements shows as approved text, rep fills left in it for the rep ([your name],{currency pair},{payee}). A point with requirements shows only once every slot it names is known, as{kind: 'approved_template', text_id, policy_version, params}with params keyed by the placeholder name without braces: a currency leg as its ISO 4217 code (pairLegs),{country}as the residency's country id;checkPointParamsrefuses anything outsidefact_lists. Otherwise the point is left out, the situation's other points still show, and a situation with none left shows "Listening". An unsourced slot is never known. The card never holds anapproved_template, so it leaves these points off; they show on the plan item. covered::for a template point keeps the approved text with its placeholders, so it stays a pure function of the playbook, cached underplaybook_hash.- Status lines:
give_status_with_specifics.2,.h2and.h1assert three mutually exclusive payment states (waiting for funds, received, gone) that no call fact establishes, and knowing the pair establishes none of them.where_is_my_moneytherefore hasapplies: {when_fact: 'trade_status_known'}, andtrade_status_knownis inUNSOURCED_FACTS: the situation is never a candidate in M1, andgive_status_with_specificsshows its title and "Listening" (§7 point 6). - Tests:
tests/unit/engine-slots.test.ts.
4. Worked examples
Each example gives the client turn, the questions the gate asks, the answers it needs and what the rep sees. They became the L1 cases in §4.6 (COPILOT-096).
4.1 Customer success: the delivery date (MUST-NOT)
Current item: agree_next_step (template transfer_issue). Candidates: ready_to_book_after_a_fix, choosing_a_delivery_date.
| Latest client turn | Questions | Required answers | Rep sees |
|---|---|---|---|
| "The payment to my supplier still hasn't arrived. Where is it?" | situation::agree_next_step, fits::ready_to_book_after_a_fix, fits::choosing_a_delivery_date |
Choice none; both fits < 0.60 |
"Agree the next step", "Listening". Never agree_next_step.h2. (If the turn opens a settlement_delay concern, the plan inserts a concern item whose move, give_status_with_specifics, has where_is_my_money, which fits there.) |
| "I can't log in, it keeps asking me for a code." | same | none; both < 0.60 (the block is not fixed yet) |
"Listening". Neither line. |
| "Great, that's all sorted, thanks for your help." | same | none; both < 0.60 |
"Listening". Not the delivery-date line, and not "You should be able to book the trade now." either: nothing was blocking a booking. |
| "Delivery date. Does it make a difference?" (while booking on the platform) | same | Choice choosing_a_delivery_date ≥ 0.40; fits::choosing_a_delivery_date ≥ 0.60 |
Headline "Which delivery date do I pick?", point agree_next_step.h2 |
| "But what I'm gonna do now is just log on and then try to reset up the two factor authentication and do the trade that I wanted to do." (after the rep fixed the two-factor problem) | same | Choice ready_to_book_after_a_fix; its fits ≥ 0.60; fits::choosing_a_delivery_date < 0.60 |
Headline "I'll log on and do the trade now.", point agree_next_step.h1 |
4.2 Customer success: where is my money (slots)
Current item: give_status_with_specifics. One candidate, where_is_my_money, so no Choice.
| Latest client turn | Required | Rep sees |
|---|---|---|
| "So are they gonna have the money today?", pair known (GBP to EUR) | none: where_is_my_money is not a candidate while trade_status_known has no source (COPILOT-097, §3.8) |
"Give the status with specifics", "Listening". Each of the three lines asserts a payment status the call has not established. Once a source exists: .2, .h2 and .h1, with {sell_currency} = GBP and {buy_currency} = EUR |
| Same, pair not known | same | "Listening". Once a source exists: .2 only (.h1 and .h2 wait for currency_pair) |
| "Which delivery date should I put for the next one?" | fits::where_is_my_money < 0.60 |
"Listening" (a new booking's date is not a payment in flight) |
4.3 Onboarding: the funding account
Current item: confirm_funding_account. Candidates: funding_owner_unclear, and bank_abroad_not_named unless the residency slot is GB.
| Latest client turn | Required | Rep sees |
|---|---|---|
| "It'll well, I've got a few options. I can put it in my daughter's account and send it over." | Choice funding_owner_unclear; its fits ≥ 0.60 |
"Whose account will the money come from, yours or someone else's?" |
| "Well, it's so so this will be transfers that I I will be doing in the future. But yeah. So from Saudi Real into Sterling. Yeah." (residency SA known) | Choice bank_abroad_not_named; its fits ≥ 0.60 |
confirm_funding_account.h1 with {country} filled from the residency value SA (COPILOT-097 renders the country's name, not the chip label "Lives in Saudi Arabia") |
| Same turn, residency not known yet | same | "Listening": confirm_funding_account.h1 waits for residency |
| "Is my money safe with you, though?" | Choice none; both fits < 0.60 |
"Listening" (if a safety concern opens, its concern item's move is explain_who_holds_the_money, where is_my_money_safe fits) |
4.4 Onboarding: who holds the money (partner gating)
Current item: explain_who_holds_the_money. Candidates: is_my_money_safe only; where_do_i_send_funds needs settlement_partner_known, which nothing sets yet.
| Latest client turn | Required | Rep sees |
|---|---|---|
| "you know, ready for a pretrade, is that FCA FCA protected?" | fits::is_my_money_safe ≥ 0.60 |
"The funds are held in a segregated account, …" |
| "So, I book it online, and it should come out with the proper rate and also send me the instructions on how, how to actually transfer the funds. Is that correct?" | fits::is_my_money_safe < 0.60 |
"Listening". explain_who_holds_the_money.h2 ("… with {settlement_bank} in {settlement_city}") is never shown until the partner is a known fact, per Stevan's 2026-09-25 ruling. |
4.5 Onboarding: rate pressure
Rate item after "Company X gives me a better rate." (rate episode competitor_named). Candidates for fits::: competitor_named and the next two by probability.
| Latest client turn | Required | Rep sees |
|---|---|---|
| "Company X gives me a better rate." | rate_objection_type = competitor_named ≥ 0.40; fits::competitor_named ≥ 0.60 |
"Rate pressure", headline, hint, "Ask first" (qualify_the_quote.1 to .4), then competitor_named.1 and .2 |
| "Sorry, can I just ask how long the transfer takes once I book?" (same episode, concern still open) | fits::competitor_named < 0.60 |
"Rate pressure", "Listening" until the client comes back to the rate |
4.6 L1 cases (COPILOT-096)
eval/labelled/like-for-like.json holds the like-for-like L1 cases for both scenarios. Each case names its own scenario, as in rate.json. The file is loaded by loadLikeForLikeCases and included in loadAllCases (scripts/lib/eval-cases.ts). It has 74 cases and 174 checks:
- Positives, one per situation (
lfl_<ob|cs>_<situation>, 49). The latest turn is copied exactly from one of the situation'sclient_examples, after a short context. Each checksfits::<id> >= 0.6. A situation of a move that has asituation::Choice also checkssituation::<move> in [<id>], and a rate situation checksrate_objection_type in [<id>]instead.qualify_the_quoteandconcession_termsget the fit check only. Where two siblings are clearly different, the positive also checks the sibling'sfits:: < 0.6. - None-of-them, one per move (
lfl_<ob|cs>_none_<move>, 25). These use the client turns listed in the story. Everyfits::of the move must be < 0.6. The case addssituation::<move> in [none]only where that Choice exists, and addsrate_objection_type in [none]for the rate moves. The three onboarding rate moves share one case (lfl_ob_none_rate_moves). The customer-successagree_next_stepcase is Stevan'slfl_cs_must_not_delivery_date.
validateCases accepts fits::<situation> as a noul and situation::<move> as a Choice over the move's candidates plus none. Both are generated from the scenario's playbook in the same way the engine asks them (gateQuestion), and anything else still fails as "not in the bank". probe-questions.mjs --cases generates the same questions for each case (assembleQuestions(…, fits)).
Live probe, 2026-09-26. Two runs gave the same totals, and the same checks failed in both. Second run:
$ node scripts/probe-questions.mjs --cases eval/labelled/like-for-like.json
…
PASS lfl_cs_choosing_a_delivery_date (customer_success)
pass fits::choosing_a_delivery_date >= 0.6: 0.96
pass situation::agree_next_step in [choosing_a_delivery_date]: choosing_a_delivery_date (1)
pass fits::ready_to_book_after_a_fix < 0.6: 0.02
…
PASS lfl_cs_must_not_delivery_date (customer_success)
pass fits::choosing_a_delivery_date < 0.6: 0.03
pass fits::ready_to_book_after_a_fix < 0.6: 0.02
pass situation::agree_next_step in [none]: none (0.99)
model: jev-1.13.0
cases: 67/74 passed (90.5%); checks: 165/174 (94.8%)
Every failing check is listed below with its proposed repair. Each repair is a policy edit for Stevan's red pen: none has been applied, and no threshold was lowered. The scores are from run 2, with run 1 in brackets.
| Case | Failing check | Got | Proposed repair |
|---|---|---|---|
lfl_ob_where_do_i_send_funds |
fits::where_do_i_send_funds >= 0.6; situation::explain_who_holds_the_money in [where_do_i_send_funds] |
0.24 (0.2); none (0.4 / 0.49) |
Drop "and the activating partner for this client is known" from what. Nothing in a client turn can show it, and applies.when_fact: settlement_partner_known already gates it (§7 point 2). |
lfl_ob_none_close_the_document_gap |
fits::selfie_missing_or_rejected < 0.6 |
0.72 (0.7) | The clause "or the client says their selfie or ID already went through" catches "I've uploaded everything and it all went through". Limit it to a selfie or ID the rep has just said was rejected, and add "a client who says all their documents went through, with no document named as missing" to not_for. |
lfl_ob_none_agree_next_step |
fits::activation_next_steps < 0.6 |
0.71 (0.71) | Add "a question about the transfer itself (how long it takes, the rate) asked at the end of the call" to not_for. The what clause "asks … when they can transfer" reads close to "how long do transfers take". |
lfl_cs_invoice_needed_for_payment |
fits::invoice_needed_for_payment >= 0.6 |
0.37 (0.4) | what requires the client to "ask what the problem is or what is needed". The client example reports what they have done ("I messaged the electrician … could he provide it"). Add "or says they have asked the payee for it". |
lfl_cs_upcoming_payments_unknown |
situation::review_upcoming_exposure in [upcoming_payments_unknown] |
none (0.7 / 0.79); fit passes at ≥ 0.6 |
The Choice reads "nothing happening" on a thank-you after a fix. Rewrite what from the rep's opportunity rather than the client's silence: "The client's issue is dealt with and the client is wrapping up or thanking the rep, and has not said what payments abroad they have coming up." |
lfl_cs_payment_mentioned_no_amount |
fits::payment_mentioned_no_amount >= 0.6; the Choice |
0.04 (0.05); none (0.75 / 0.77) |
The harvest example "I just didn't wanna screw things up the fur I'm gonna be doing it probably a little more frequently over the next few months." is too weak for this situation. Replace it with a clearer one, or broaden what to "says they will be making transfers (more often, soon, over the coming months)". |
lfl_cs_several_payments_at_once |
fits::several_payments_at_once >= 0.6 |
0.59 (0.55) | The example ("eight supplier invoices to pay this week") does not say they book them "at the same time". Change what to "pays several different people or suppliers in the same week or run". |
5. Before the gate (history)
Superseded by COPILOT-095b (2026-09-26): pointsOf(move, shown, p) now shows only the situation the current item's gate shows, and there is no fallback to the first situation or to flat lines for a move with situations (§3.7). What follows describes the tree between the restructure and the gate.
The engine in the tree today reads the restructured policy through pointsOf (src/engine/situation.ts): the open rate episode's situation, else the move's approved flat lines, else the first situation with an approved point. After the restructure no move has an approved flat line, so each move shows its first situation, with all its points. The situations are ordered so that the first is the most general:
- Customer success
agree_next_stepshowsready_to_book_after_a_fix("You should be able to book the trade now."); the delivery-date line is not shown at all until 095. confirm_funding_accountshowsfunding_owner_unclear(the open question);close_the_document_gapshowsdocuments_outstanding_next_step;explain_who_holds_the_moneyshowsis_my_money_safe;explain_document_requestshowswhich_statement_needed;review_upcoming_exposureshowsupcoming_payments_unknown.- A real bundle has no
phrasing::Choice any more (they exist only for approved flat lines); a fixture bundle still has some, because--approve-as fixtureapproves the drafts left inlines[], andpointsOfprefers those flat lines.
Nothing is published from this state: a real bundle is still refused by the loader for its draft lines and [VERIFY markers, exactly as before the restructure.
6. Tests, fixtures and the red-pen sheet
Unit suite in the worktree (npx vitest run tests/unit): 7 failures before the restructure, all from red-pen rounds 1 to 6 changing policy/src without the tests (the four stale committed fixtures, the phrasing:: id list, the fixture line counts, the REDPEN counts). After it, 10. The three new failures are tests that pin the old structure; none is a defect, and COPILOT-095 carries the fixes:
| Test | Why it fails now | Fix (095) |
|---|---|---|
tests/unit/policy-drafts.test.ts "every move, line and situation point is well formed" |
A point's text_id must be <situation id>.<n>; moved lines keep their move's id (open_with_agenda.h1 under call_just_answered) |
A point's id is <situation id>.<n> or, for a line moved in, <its move id>.<n> / .h<n> |
tests/unit/policy-text.test.ts "refuses a duplicate text_id when the scheme is kept" |
It duplicates the first move, which now has a situation, so the duplicate-situation check fires first | Duplicate a move without situations, or expect either refusal |
tests/unit/policy-retired.test.ts "a retired situation point is dropped from the bundle" |
It retires the first point of the playbook's first situation, now call_just_answered's only point, which is its core |
Retire a non-core point of a situation with two or more points (qualify_the_quote.1) |
The committed fixtures (tests/fixtures/policy/*.fixture.json) were deliberately not regenerated. The stub answers (tests/fixtures/answers/*.stub.json) pin the fixture policy_hash, and regenerating only the policy fixtures breaks engine-step, engine-plan and engine-fact-values (24 failures in a sandbox copy). With both regenerated (sandbox), the four stale-fixture tests and the budget pass, and eight engine tests that pin the old flat lines of the fixture fail instead (engine-card lines ×3, engine-budget phrasing_beyond_top4, engine-covered ×3, engine-situations situationsOf). COPILOT-095 regenerates both and rewrites those tests for the gate.
policy/REDPEN.md lists every situation under its move: headline, hint, what, not_for, applies in words, every client example ("Client example (source): text"), the core line, and the points with status and their placeholders (slot requirements and rep fills), since COPILOT-095. §8 below keeps the provenance of each client example.
COPILOT-095b rewrote them, and every other engine test the gate changes, against the gate: the card and plan tests that expected the open rate episode's situation (or a move's first situation) without a fit now name the situation and the fits:: answer that shows it (engine-card, engine-situations, engine-plan, engine-covered, engine-rate, policy-retired); the phrasing:: tests run on a copy of a move without situations. With the gate the exemplar replays show few points (the stub fits a situation only on the turns STUB_FITS names), so engine-covered's count of replay requests carrying a covered:: noul went from more than 50 to at least one. Unit suite after 095b: 842 passed, 0 failed.
COPILOT-095 regenerated both fixture sets and made those fixes. The unit suite then fails exactly the eight engine tests that pin the old flat lines (engine-card "pickCard: lines" ×3, engine-budget "phrasing_beyond_top4 keeps the card move…", engine-covered ×3, engine-situations "a move without the chosen situation gets none…"); COPILOT-095b rewrites them against the gate. The other phrasing:: budget tests run on a copy of the fixture without situations, because a move with situations no longer gets a phrasing:: Choice.
npm run typecheck exits 0 (the restructure touches JSON only).
7. Open points for Stevan
Headlines and hints of the 35 new situations are drafts: red-pen them like move headlines (
situation.<id>.headline,situation.<id>.hint).where_do_i_send_funds(explain_who_holds_the_money.h2) can never show:settlement_partner_knownis not a signal andsettlement_partneris not a fact slot. COPILOT-095 adds the fact; its source (the rep's screen or the call) is your call.reengage_dormant_with_a_reason.1("You last transferred in {month}; …") waits forlast_transfer_month, which nothing supplies in M1; its alternate.3shows instead. Should{month}be a rep fill?putting_off_booking(offer_forward_for_known_future_payment.h1, "Do you still want to lock the rate in today?") was said to a client spreading bookings over the next four nights, which the move's ownnot_forexcludes ("Payments due within days"). Keep it under the forward move, or move it?open_with_agenda.h1writes its placeholder{currency pair}with a space; code placeholders are{snake_case}. It is a rep fill today; normalise it if code should fill it from the pair chip.give_status_with_specifics: the three status lines answer one client question and differ by the trade status only the rep sees. Each asserts a status (waiting for funds, received, gone) that no call fact establishes, so since COPILOT-097where_is_my_moneyis gated ontrade_status_known, which nothing sets: none of the three is ever on screen in M1, and the item shows its title and "Listening". Lifting it is your ruling: a source for the trade status, or alternates the rep chooses from the screen.set_up_recurring_or_batch.4was deleted by COPILOT-095 (it existed only for the build).Rate situations: their
whatis now literal; the old framing is innote. Thebank_matchedheadline was 9 words, and COPILOT-095's builder refuses more than 8, so it now reads "I spoke to my bank; they matched you." (draft; red-pen it). The PDF's client line, "I spoke to my bank and they've matched you.", stays verbatim as its client example.choosing_a_delivery_date'swhatwas sharpened by COPILOT-095's live probe (§3.6): it required "booking a transfer on the platform during the call", which a client turn cannot show, and scored 0.33 on "Delivery date. Does it make a difference?". It now reads "The client asks about the delivery date of a transfer they are booking or about to book: which date to choose, whether the date makes a difference, why a date is not available, or whether it can go today." Red-pen it; the MUST-NOT case still scores 0.03.Budget: the gate and the rate group do not fit together (COPILOT-095b, §3.4). With a rate-type concern open, onboarding's request is over the 11,000 soft budget before any gate question, so the gate is always dropped and the rate item shows "Rate pressure" and "Listening" for the whole episode; in customer success the three
fits::of the rule push it over. Options, all a policy or spec change rather than a code default: ask only the episode'sfits::on the rate item (the decision rule reads no other; −475 tokens), move the gate's drop afterwindow_to_8, trim the rate group (the five do-not nouls are rep-turn only), or raise the soft budget toward the 12,000 hard cap. Until one is chosen, rate points reach the screen only in customer success on short windows.check_serviceability_first.h1cannot reach the screen on its item (COPILOT-097). "Have you been working in {country} for a while?" needs the residency slot, and the onboarding plan itemcheck_serviceability_firsthasdone_when: [{slot: 'residency'}], so the item is done on the same decision the residency becomes known and the plan moves on. The engine fills the point correctly when the item is current (tests/unit/engine-slots.test.ts), and the card leaves template points off. Options: keep the item open until the serviceability question is asked (amust_sayindone_when), move the line to an item that is still open once residency is known, or accept that it never shows.confirm_funding_account.h1is not affected.
8. Situations by scenario (red-pen copy)
Provenance: harvest <call:utt> prev|next is the client turn's place in data/analysis/harvest/turns.jsonl (the prev or next client turn of that candidate rep turn): "right before the line" = the client turn immediately before a rep turn of the line's cluster; "same call, earlier" = an earlier client turn of that call (the immediate one was a backchannel); "other call" = a matching client turn from another harvested call, found by keyword.
Onboarding
open_with_agenda (Set the agenda)
Flat lines left: open_with_agenda.1 (draft), open_with_agenda.2 (draft), open_with_agenda.3 (draft).
call_just_answered: "Hello? Who's speaking?"
- What: The call has just connected. The client has only answered or asked who is calling ('Hello?', 'Yes, speaking', 'Who's this?'), and the rep has not yet said who they are, that they are calling from Currency Transfer, or what the call is about.
- Not for: Any point after the rep has introduced themselves and said why they are calling; a call the client placed to us or is returning; a client who opens with their own question about a transfer, a document or a problem.
- Applies: always
- Points:
open_with_agenda.h1(core) [approved]: My name is [your name]. I'm calling from Currency Transfer. It's just regarding an application you made with us to transfer {currency pair}. (rep fills[your name],{currency pair}) - Client examples:
- "Yes. Who's speaking?" (harvest
3551637651:7prev, right before the line) - "Yeah. Speaking. Who is this?" (harvest
3754998213:5prev, right before the line) - "Hello? Yes." (harvest
3600194928:1prev, right before the line)
- "Yes. Who's speaking?" (harvest
check_serviceability_first (Check we can serve them)
Flat lines left: check_serviceability_first.1 (draft), check_serviceability_first.2 (draft), check_serviceability_first.3 (draft).
works_abroad: "I'm working abroad at the moment."
- What: The client has said they live or work in a country other than the UK ('I work in Saudi', 'I'm based out of Qatar'), and nobody in the call has yet asked how long they have been there.
- Not for: A client who lives in the UK; a client who has only said where the money is going or which currency they sell, since a destination or a currency is not where they live; a client whose UK address is the open question; a question about the rate, safety or documents.
- Applies:
residencynot in GB (unknown keeps it) - Points:
check_serviceability_first.h1(core) [approved]: Have you been working in {country} for a while? (needs{country}fromresidency) - Client examples:
- "Currently, I'm working in Saudi Arabia, and I do have asset in Australia that I need to transfer from time to time" (harvest
3209639827:21next, other call) - "So I I work in I I'm British as in but I work in Saudi," (harvest
3895698114:13next, other call) - "I'm working in Lithuania at the moment." (harvest
3688041601:62prev, other call)
- "Currently, I'm working in Saudi Arabia, and I do have asset in Australia that I need to transfer from time to time" (harvest
uk_address_unclear: "I don't live in the UK anymore."
- What: The client has said they moved abroad, no longer live at a UK address, or that the address they gave us is not their real or current one, and nobody has yet asked whether they still have a UK address.
- Not for: A client who has said they live at a UK address; a client who works abroad but has said nothing about their address; a question about which document proves their address.
- Applies: always
- Points:
check_serviceability_first.h2(core) [approved]: Do you have a UK address? - Client examples:
- "I It's not a It's not the correct address. I just put in a made up address to get through." (harvest
1364651512:58prev, right before the line) - "So I was like, that's crazy. I don't live there anymore, and I've got I've been here for so long." (harvest
3886794288:75prev, same call, earlier) - "So I've recently moved out to Saudi Arabia. I'll be spending at least sort of eight months a year out here." (harvest
3462835774:6next, other call)
- "I It's not a It's not the correct address. I just put in a made up address to get through." (harvest
ask_about_the_transfer (Ask an open question about the transfer)
Flat lines left: ask_about_the_transfer.1 (draft), ask_about_the_transfer.2 (draft), ask_about_the_transfer.3 (draft).
amount_not_said: "I'd like to send some money over."
- What: The client has said they want to make a transfer, or has described it (what it is for, the currencies or the country), but nobody in the call has said an amount, and the client's latest turn is not a question or a problem of their own.
- Not for: A client who has already given an amount or a range; a client whose latest turn asks a question (how it works, whether it is safe, how long it takes) or raises a problem, which needs answering first; a call where the transfer has not come up yet.
- Applies: always
- Points:
ask_about_the_transfer.h1(core) [approved]: And how much are you looking to transfer? - Client examples:
- "Okay. I I would like to understand how it works because I need to buy euro." (harvest
3683594440:2next, same call, earlier) - "It's from US to pounds." (harvest
3588426502:30next, same call, earlier) - "Yes. Because I'm living in Australia." (harvest
3558675049:21prev, right before the line)
- "Okay. I I would like to understand how it works because I need to buy euro." (harvest
first_transfer_date_not_said: "I know what I'm sending, not when."
- What: The client has described what they want to send (the amount, how often, or what it is for), but nobody has said when the first transfer will be, and the client's latest turn is not a question or a problem of their own.
- Not for: A client who has already said when they will send it (a date, 'this week', 'after completion'); a client whose latest turn asks a question or raises a problem; a client who has not yet said what they want to send.
- Applies: always
- Points:
ask_about_the_transfer.h2(core) [approved]: When are you looking to make your first transfer? - Client examples:
- "No. Every month. My you know, every month, I'm sending probably half of my salary back to The UK." (harvest
3217828966:9next, same call, earlier) - "Probably once every three months, I'll I'll send or" (harvest
3023513511:34next, same call, earlier)
- "No. Every month. My you know, every month, I'm sending probably half of my salary back to The UK." (harvest
pin_down_timing_and_amount (Pin down amount and date)
Flat lines left: pin_down_timing_and_amount.1 (draft), pin_down_timing_and_amount.2 (draft), pin_down_timing_and_amount.3 (draft).
plans_described_no_amount: "I'll be sending money over the coming months."
- What: The client has explained what the money is for, or described transfers over the coming weeks or months (a property, salary, family support, a bigger transfer this time), but has not said how much the next transfer will be.
- Not for: A client who has already given the amount of the next transfer; a client who has not yet said what the transfer is for; a client whose latest turn asks a question or raises a concern.
- Applies: always
- Points:
pin_down_timing_and_amount.h1(core) [approved]: What is the amount that you plan to transfer?pin_down_timing_and_amount.h2[approved]: What's the immediate amount you plan to send, and when?
- Client examples:
- "So this is why this is the why because I live there, so she needs to transfer the money from here to there." (harvest
3887777022:30prev, right before the line) - "And so over the next two years, but it could be, like, in the next six months or it could be all the way up to two years. Just trying to find the right place." (harvest
3283775356:15prev, right before the line) - "the transfer I'm gonna make or wanting to make is probably gonna be more significant this time. Otherwise, it's just to cover things back home that go out of our UK accounts still." (harvest
3535280464:25prev, right before the line)
- "So this is why this is the why because I live there, so she needs to transfer the money from here to there." (harvest
confirm_funding_account (Confirm the funding account)
Flat lines left: confirm_funding_account.1 (draft), confirm_funding_account.2 (draft), confirm_funding_account.3 (draft).
funding_owner_unclear: "It might come from my husband's account."
- What: The first transfer is being discussed and nobody has established whose account the money will leave from; or the client has mentioned a spouse, relative, partner or company in connection with paying, without saying whose account it will come from.
- Not for: A client who has already said the money comes from an account in their own or their company's name; a client who has already said another named person will send it, which needs the third-party rule explained rather than a question; a question only about which bank or country the money comes from.
- Applies: always
- Points:
confirm_funding_account.h2(core) [approved]: Whose account will the money come from, yours or someone else's? - Client examples:
- "It'll well, I've got a few options. I can put it in my daughter's account and send it over." (harvest
3343977959:3next, other call) - "Like, maybe it's just coming all from my husband's account or all from" (harvest
3422982443:63next, other call) - "The question, can I fund this transaction from my American personal account, or can I fund it from my American company account?" (harvest
3564664484:19prev, other call)
- "It'll well, I've got a few options. I can put it in my daughter's account and send it over." (harvest
bank_abroad_not_named: "I'll be sending it from my account abroad."
- What: The client will send money from a bank account outside the UK (they have said the country, or that they sell that country's currency from an account there), and has not named the bank.
- Not for: A client funding from a UK bank account; a client who has already named their bank; a question about whose name the account is in.
- Applies:
residencynot in GB (unknown keeps it) - Points:
confirm_funding_account.h1(core) [approved]: And who is it that you bank with in {country}? (needs{country}fromresidency) - Client examples:
- "Well, it's so so this will be transfers that I I will be doing in the future. But yeah. So from Saudi Real into Sterling. Yeah." (harvest
4031061209:9prev, right before the line) - "It's SAR, GBP, and GBP SAR." (harvest
3406611968:23prev, right before the line) - "To Sweden from Saudi." (harvest
3137412533:11prev, right before the line)
- "Well, it's so so this will be transfers that I I will be doing in the future. But yeah. So from Saudi Real into Sterling. Yeah." (harvest
close_the_document_gap (Name the missing document)
Flat lines left: close_the_document_gap.1 (draft), close_the_document_gap.2 (draft), close_the_document_gap.3 (draft).
documents_outstanding_next_step: "So what's the next step with the documents?"
- What: Verification documents are still missing, and the client asks what happens next or what they need to send, or says they will send the documents later.
- Not for: A client whose documents are complete; a question about one specific document, such as the proof-of-life selfie; a client asking why a document is needed for a payment after activation.
- Applies: always
- Points:
close_the_document_gap.h2(core) [approved]: I'll send you an email asking for the documents. - Client examples:
- "okay, so what's the next step? There's there's some documents that need to be uploaded, I I gather." (harvest
4149992351:149prev, right before the line) - "It won't be till this evening. But if you send me an email requesting the information, I'll look at it this evening and send it over." (harvest
4122196332:39prev, other call)
- "okay, so what's the next step? There's there's some documents that need to be uploaded, I I gather." (harvest
selfie_missing_or_rejected: "I already sent you the selfie."
- What: The proof-of-life selfie is missing or was not accepted (the ID was not held next to the face, or a different ID was used), or the client says their selfie or ID already went through, or offers to send the ID separately.
- Not for: Other documents such as proof of address or a bank statement; a client whose documents are all accepted; a general question about what happens next.
- Applies: always
- Points:
close_the_document_gap.h1(core) [approved]: With the proof of life selfie, hold your passport next to your face; it's just to verify you're a real person. - Client examples:
- "Everything an everything attachment. came through. Yeah. So everything everything else came through. The, I believe, the other the ID and the selfie." (harvest
3462835774:39prev, right before the line) - "I chunk can send of you the that as well as that as a separate document, the actual passport if you want." (harvest
3604013068:39prev, right before the line) - "a passport was better in terms of ID, but that's fine." (harvest
3684944575:18prev, right before the line)
- "Everything an everything attachment. came through. Yeah. So everything everything else came through. The, I believe, the other the ID and the selfie." (harvest
explain_who_holds_the_money (Explain who holds the money)
Flat lines left: explain_who_holds_the_money.1 (draft), explain_who_holds_the_money.2 (draft), explain_who_holds_the_money.3 (draft).
is_my_money_safe: "Is my money protected with you?"
- What: The client asks whether their money is safe or protected, who holds it, whether the service is regulated (FCA), or what happens to their funds if something goes wrong.
- Not for: A question about where to send the money or which account it goes into; a question about the rate, the fees or how long the transfer takes.
- Applies: always
- Points:
explain_who_holds_the_money.h1(core) [approved]: The funds are held in a segregated account, so they cannot be used for business operations; they're held entirely separate. - Client examples:
- "you know, ready for a pretrade, is that FCA FCA protected?" (harvest
3286751956:73prev, same call, earlier) - "FCA broker? What what is your com what do your com what does your company do?" (harvest
3354912148:100prev, same call, earlier)
- "you know, ready for a pretrade, is that FCA FCA protected?" (harvest
where_do_i_send_funds: "Where do I actually send the money?"
- What: The client asks where they send their money after booking, which account it goes into, or whose name that account is in, and the activating partner for this client is known.
- Not for: A question about whether the money is safe or regulated; a client whose activating partner is not known yet, because the account structure differs by partner; a question about how long the money takes to arrive.
- Applies: once
settlement_partner_knownis held - Points:
explain_who_holds_the_money.h2(core) [approved]: This is going to be an account in your name, but it will be with {settlement_bank} in {settlement_city}. (needs{settlement_bank}fromsettlement_partner,{settlement_city}fromsettlement_partner; line applies oncesettlement_partner_knownis held) - Client examples:
- "So, I book it online, and it should come out with the proper rate and also send me the instructions on how, how to actually transfer the funds. Is that correct?" (harvest
3883579860:55prev, same call, earlier) - "how does yours work? Is it an instant change and or, like, does it go into a different account" (harvest
3646184940:121next, same call, earlier)
- "So, I book it online, and it should come out with the proper rate and also send me the instructions on how, how to actually transfer the funds. Is that correct?" (harvest
show_the_rate_against_mid_market (Compare the rate against mid-market)
Flat lines left: none.
mid_market_comparison: "Why am I getting less than Google says?"
- What: The client compares our rate with the mid-market or interbank rate they saw on Google, XE or a similar site, and asks why ours is lower or different.
- Not for: A rate quoted by a bank or another provider.
- Applies: always
- Points:
mid_market_comparison.1[approved]: That's the mid-market rate. It's the midpoint between buying and selling, so it's a reference number rather than a price. Nobody trades at it, banks included.mid_market_comparison.2(core) [approved]: The number worth comparing is what actually lands from us against what actually lands from your bank, same day, same amount.
- Client examples:
- "Google says 1.2740. Why am I getting 1.2690?" (PDF)
- "the currency conversion is the same as the one that Google depicts, but normally it should be half the one that Google depicts." (harvest
1378338645:7prev, other call)
explain_settlement_and_cutoff (Explain when the money arrives)
Flat lines left: explain_settlement_and_cutoff.2 (draft), explain_settlement_and_cutoff.3 (draft).
when_will_it_arrive: "How long does it take to arrive?"
- What: The client asks how long a transfer takes, when the money will arrive or whether it can land the same day, or names a date the money must arrive by.
- Not for: A question about when their account will be activated or their documents checked; a question about whether their money is safe or who holds it.
- Applies: always
- Points:
explain_settlement_and_cutoff.1(core) [approved]: For major currencies, if your funds reach the partner before their cut-off, usually 2pm UK time, it settles the same day. Other currencies can take up to five working days. - Client examples:
- "If I book it on a Monday morning, will it get there the same day?" (drafted)
- "The money has to be in the solicitor's account by the end of next week. How long does it take?" (drafted)
- "Okay. And then once I initiate the the transfer, how long does it take to get to the other party?" (harvest
3766832820:81next, other call)
explain_booking_is_binding (Explain that a booking is binding)
Flat lines left: explain_booking_is_binding.1 (draft), explain_booking_is_binding.2 (draft), explain_booking_is_binding.3 (draft).
learning_to_quote_and_book: "So I get a quote, then book?"
- What: The client is being shown, or asks, how quoting and booking work ('so I get a quote, then book?'), says they will get a quote or book, or asks whether a booking can be cancelled or changed.
- Not for: A client who has already been told that a booking is binding; a question about how long the transfer takes after booking; a client who only asks for today's rate.
- Applies: always
- Points:
explain_booking_is_binding.h1[approved]: You can quote and see the amount you'd get, but don't book unless you're happy to make the transfer and happy with the amount.explain_booking_is_binding.h2(core) [approved]: Cancelling a trade can result in losses, because it's a live trade.
- Client examples:
- "And then you'll get a quote." (harvest
4114088996:47prev, right before the line) - "doing doing this, this, like, like, 15 fifteen times a times day a or day whatever." (harvest
3382788633:98prev, right before the line) - "If the rate drops after I book, can I just cancel it?" (drafted)
- "And then you'll get a quote." (harvest
handle_rate_objection (Handle a rate objection)
Flat lines left: none.
qualify_the_quote: "Qualify the quote before you respond"
- What: The client cites a rate or quote from another provider or their bank (a number, or 'they give me a better rate'), and the rep has not yet asked when they got it, whether it was a live quote on their amount, what the fees on top were, or what actually landed.
- Not for: A request for a better rate with no competing number ('Can you do better than that?'); a comparison with the mid-market rate on Google or a similar site; the four questions already asked.
- Applies: always
- Points:
qualify_the_quote.1[approved]: When did you get that rate?qualify_the_quote.2[approved]: Was that a live quote on your amount, or a headline off a website?qualify_the_quote.3[approved]: What were the fees on top, including the receiving bank's cut?qualify_the_quote.4(core) [approved]: What actually landed in the beneficiary account last time, against what you were quoted?
- Client examples:
- "Company X gives me a better rate." (PDF)
- "Another broker quoted me a better rate on the same amount last week." (drafted)
no_quote_in_hand: "Can you do better than that?"
- What: The client asks for a better rate or price ('Can you do better than that?', 'Is that the best you can do?') without naming another provider's rate, a bank quote, or the rate on Google.
- Not for: A client who names a competitor's rate, cites the mid-market rate, or says their bank matched: if a real comparator comes back, you are no longer in this objection.
- Applies: always
- Points:
no_quote_in_hand.1[approved]: Better than what?no_quote_in_hand.2(core) [approved]: No. That's the price.no_quote_in_hand.3[approved]: And it's live, so it's moving while we talk. Do you want it, or shall I requote in ten?
- Client examples:
- "Can you do better than that?" (PDF)
- "Is that really the best rate you can give me?" (drafted)
competitor_named: "Company X gives me a better rate."
- What: The client says another provider (a named company, a broker, their other platform) gives or offered them a better rate, usually with a number.
- Not for: The client's own bank matching us after hearing from us; a number off Google or a similar site; a request for a better rate with no comparator.
- Applies: always
- Points:
competitor_named.1[approved]: They probably do on the first one. What matters is what you're getting on trade twenty, when nobody's watching.competitor_named.2(core) [approved]: Pull your last three confirmations from them and let's compare what landed, not what was quoted.
- Client examples:
- "Company X gives me a better rate." (PDF)
- "My other broker gave me a better rate than this on my last transfer." (drafted)
concession_terms: "If you do move on price"
- What: The rep is about to move on price or has just offered a better rate, or the client asks what it would take to get a better rate (more volume, moving other payments, a forward, an introduction).
- Not for: Any of the five rate objections answered without moving on price.
- Applies: always
- Points:
concession_terms.1[approved]: Volume. A monthly or quarterly commitment that puts them in the band you are pricing them at.concession_terms.2[approved]: Consolidation. The corridors they currently run elsewhere come to you.concession_terms.3[approved]: Forward cover. The next tranche booked forward rather than left to shop.concession_terms.4[approved]: Introduction. The finance contact at the group company, the supplier, the sister office.concession_terms.5(core) [approved]: The rate is one number on one day. What you're paying for is knowing what it'll be worth when it lands and when it'll get there. If you press send and then spend two days chasing, the half pip you saved cost you more than it was worth.
- Client examples:
- "What would it take for you to sharpen that rate?" (drafted)
- "If I moved all my payments over to you, could you do better?" (drafted)
handle_alternative_provider (Address the bank, Wise or Revolut comparison)
Flat lines left: handle_alternative_provider.2 (draft), handle_alternative_provider.3 (draft).
serial_shopper: "I'll just check what the others are doing."
- What: The client says they will check other brokers or providers before booking, or that they compare several providers on every trade ('I'll just check what the others are doing').
- Not for: A client with one competing quote already in hand; a client checking a provider for the first time who has not said they shop around.
- Applies: always
- Points:
serial_shopper.1(core) [approved]: Happy to quote you every time. If you want a better number without the ring-around, give me the flow for the quarter and I'll price it properly. - Client examples:
- "I'll just check what the others are doing." (PDF)
- "I've been just jumping between the two systems to just see which is giving me the best rates." (harvest
3229603540:13prev, other call) - "I'll log in periodically just to test you out and see if you're any better" (harvest
3816856901:31prev, other call)
bank_matched: "I spoke to my bank; they matched you."
- What: The client says their bank has matched or beaten our rate since they started talking to us.
- Not for: A bank quote the client had before talking to us, or another provider's rate.
- Applies: always
- Points:
bank_matched.1(core) [approved]: Good. That's the first time they've sharpened up for you. Ask them to hold it in writing for the next twelve months and see what comes back.bank_matched.2[approved]: Worth looking at what they were giving you before we started quoting. That's their real price, the one that applies when nobody's pushing.
- Client examples:
- "I spoke to my bank and they've matched you." (PDF)
- "My bank came back and said they'll do the same rate as you." (drafted)
offer_alert_instead_of_waiting (Offer a bookable rate alert)
Flat lines left: offer_alert_instead_of_waiting.2 (draft).
waiting_for_a_better_rate: "I'll hold off until the rate improves."
- What: The client says they want to wait for the exchange rate to improve before sending, asks whether the rate will go up or down, or names a rate they are hoping for, and has not said the money must arrive by a particular date.
- Not for: A client who says our rate is too high or that someone else offers better (a rate objection: never offer an alert then); a client with a date the money must arrive by; a client ready to book now.
- Applies: always
- Points:
offer_alert_instead_of_waiting.1(core) [approved]: Nobody can predict the rate, but you can set a bookable alert at the level you'd be happy with, and it'll book or notify you the moment it's hit.offer_alert_instead_of_waiting.h2[approved]: Have you thought of setting a rate alert or a market order? If your target rate triggers, even briefly, you'd achieve it.offer_alert_instead_of_waiting.h1[approved]: It's worth knowing that on our platform you can set rate alerts, and even bookable ones.
- Client examples:
- "After looking at the what the exchange rates are at the moment, I looked at it last night. I thought I'm just gonna hold off for a little bit" (harvest
3782650192:23next, other call) - "It's not looking promising, but I'm just waiting to check, see if it goes up a bit." (harvest
3103429322:26next, other call) - "I will exchange some, a big amount, when it is close to point four, I reckon, if it gets there." (harvest
3680366694:14prev, other call)
- "After looking at the what the exchange rates are at the moment, I looked at it last night. I thought I'm just gonna hold off for a little bit" (harvest
waiting_but_has_a_date: "I'd wait, but I have a deadline."
- What: The client wants to wait for a better rate, and has also said the money has to arrive by a particular date or event (a completion, a deposit, a fee deadline).
- Not for: A client waiting for a better rate with no date; a client with a deadline who wants to book now; a rate objection.
- Applies: always
- Points:
offer_alert_instead_of_waiting.3(core) [approved]: If there's a date the money has to be there by, an alert with a fallback date protects you both ways. - Client examples:
- "I'd rather wait for the rate to pick up, but the deposit has to be paid by the end of the month." (drafted)
- "Can I hang on and see if it improves? It just has to land before completion." (drafted)
agree_next_step (Agree the next step)
Flat lines left: agree_next_step.1 (draft), agree_next_step.2 (draft), agree_next_step.3 (draft).
activation_next_steps: "So what happens now?"
- What: The call is ending while the client's account is not yet activated: the rep has taken the details or asked for the remaining documents, and the client asks what happens next or when they can transfer, or says they have no more questions.
- Not for: An account that is already activated, so the client can book now; a client whose question or concern is still being answered; a call where the client's details have not been taken yet.
- Applies: always
- Points:
agree_next_step.h1(core) [approved]: I'll take the next steps to get you activated; if you have any questions get in touch, and you'll hear from us once activated. - Client examples:
- "So when the papers are ready, can I transfer?" (harvest
3270166872:25prev, same call, earlier) - "Is it possible to get the instruction by email?" (harvest
3974102611:89next, same call, earlier)
- "So when the papers are ready, can I transfer?" (harvest
Customer success
resolve_the_issue_first (Deal with the live issue before anything else)
Flat lines left: resolve_the_issue_first.1 (draft), resolve_the_issue_first.2 (draft), resolve_the_issue_first.3 (draft).
cancel_payment_at_own_bank: "My bank won't let me change it."
- What: The client wants to stop, cancel or change a payment they sent from their own bank (a wrong amount, wrong details or a duplicate), and the payment is still with their bank.
- Not for: A payment the partner already holds, or a booked trade the client wants to cancel with us; a question about where a payment is; a document request on a payment.
- Applies: always
- Points:
resolve_the_issue_first.h1(core) [approved]: Give them a call and ask if there's any way you can cancel that transaction. - Client examples:
- "just it doesn't give an option to change it." (harvest
4176027086:84prev, right before the line) - "I've made a payment to Denmark and I want to stop it. Is there any chance that can happen?" (harvest
3298516365:6prev, same call, earlier)
- "just it doesn't give an option to change it." (harvest
give_status_with_specifics (State the status with specifics)
Flat lines left: give_status_with_specifics.1 (draft), give_status_with_specifics.3 (draft).
where_is_my_money: "Will they have the money today?"
- What: The client asks where their payment is, when the recipient will get the money, or whether it will arrive today, about a transfer that is already booked or paid for.
- Not for: Choosing a delivery date on the booking screen for a new transfer; a document request holding the payment; the rate; a problem with a payment still at the client's own bank.
- Applies: always
- Points:
give_status_with_specifics.2[approved]: It's showing as waiting for funds: the partner hasn't received your transfer yet. Can you check the reference you used?give_status_with_specifics.h2(core) [approved]: We've already received your {sell_currency}; the {buy_currency} should be released today as soon as the partner opens. (needs{sell_currency}fromcurrency_pair(sell leg),{buy_currency}fromcurrency_pair(buy leg))give_status_with_specifics.h1[approved]: The funds have already gone, so the {buy_currency} should be with you very shortly. (needs{buy_currency}fromcurrency_pair(buy leg))
- Client examples:
- "So are they gonna have the money today?" (harvest
4027274815:34prev, right before the line) - "I have just made the transfer few minutes ago, then I got a message from email to contact you to make a location for the transfer." (harvest
3771171071:6prev, right before the line) - "And then, well, like, how will I know when it lands there?" (harvest
3335878904:31prev, same call, earlier)
- "So are they gonna have the money today?" (harvest
explain_document_request (Explain why a document was requested)
Flat lines left: explain_document_request.1 (draft), explain_document_request.2 (draft), explain_document_request.3 (draft).
which_statement_needed: "What exactly do you need, a bank statement?"
- What: A bank statement or other proof of where the funds came from has been requested, and the client asks what exactly they need to send (which account, a screenshot, a full statement).
- Not for: A request for invoices or a contract for a payment; identity documents for opening the account; a complaint about being asked at all, where the reason needs explaining first.
- Applies: always
- Points:
explain_document_request.h1(core) [approved]: A bank statement for the account the funds are sent from. - Client examples:
- "Yeah. Okay. And so what do you want? Bank statement." (harvest
3392621819:90prev, right before the line) - "What what would it have to be? Like, a screenshot of the bank account statement or the the kind of the just a screenshot of the account or or what" (harvest
3187804459:26next, same call, earlier) - "you do you want do you want me to ask that from my bank, or you just need an email? Like, what what are you what are you asking for specifically?" (harvest
4169392543:7prev, same call, earlier)
- "Yeah. Okay. And so what do you want? Bank statement." (harvest
invoice_needed_for_payment: "What's the problem with my payment?"
- What: The rep is calling, or the client has heard, about a payment held until an invoice or contract for the payee is provided, and the client asks what the problem is or what is needed.
- Not for: A request for a bank statement or proof of funds; a payment delayed for another reason.
- Applies: always
- Points:
explain_document_request.h2(core) [approved]: We just require the invoices for the payments going to {payee}. (rep fills{payee}) - Client examples:
- "Oh, you're calling from currency yes. What is the problem?" (harvest
4171898643:8prev, right before the line) - "I after you emailed me, I messaged the electrician and said, that you were asking for this extra information and could he provide it." (harvest
3865158989:5next, same call, earlier)
- "Oh, you're calling from currency yes. What is the problem?" (harvest
review_upcoming_exposure (Ask about upcoming payments)
Flat lines left: review_upcoming_exposure.2 (draft), review_upcoming_exposure.3 (draft).
upcoming_payments_unknown: "That's all sorted now, thanks."
- What: The client's issue, if there was one, is dealt with, and the client has not said what payments abroad they have coming up (amounts or dates).
- Not for: A problem that is still open; a client who has already described their upcoming payments; a client who has said they have nothing planned.
- Applies: always
- Points:
review_upcoming_exposure.1(core) [approved]: What do you have coming up over the next few months in terms of payments abroad? - Client examples:
- "Great, that's sorted then. Thanks for looking into it." (drafted)
- "No, that was the only thing I was calling about." (drafted)
payment_mentioned_no_amount: "I'll be doing more of these soon."
- What: The client mentions a payment or transfers they need to make soon, but has not said roughly how much.
- Not for: A client who has already given the amount; a problem with a payment already in flight.
- Applies: always
- Points:
review_upcoming_exposure.h1(core) [approved]: How much, roughly, do you need to do? - Client examples:
- "I just didn't wanna screw things up the fur I'm gonna be doing it probably a little more frequently over the next few months." (harvest
3229105743:48next, other call) - "So I I need to set up another payment transaction, don't I, from my" (harvest
3649020073:13next, other call) - "Yeah. So maybe if you could is it could you just email those details and the right the correct reference across to me?" (harvest
3032202073:44prev, same call, earlier)
- "I just didn't wanna screw things up the fur I'm gonna be doing it probably a little more frequently over the next few months." (harvest
offer_forward_for_known_future_payment (Offer a forward for a known future payment)
Also shows (through situation_refs): concession_terms.
Flat lines left: offer_forward_for_known_future_payment.2 (draft), offer_forward_for_known_future_payment.3 (draft).
future_payment_rate_worry: "What if the rate moves before I pay?"
- What: The client has a specific payment due weeks or months ahead, with a rough amount and date, and says they are worried the rate will move before then or asks whether they can fix today's rate.
- Not for: A payment due within days; a client with no specific future payment; a client who has already been told how a forward works and declined.
- Applies: always
- Points:
offer_forward_for_known_future_payment.1(core) [approved]: For a payment that far out you can fix today's rate with a forward: a deposit at booking, typically ten percent, and the balance at the agreed date. - Client examples:
- "The final payment to the builder is due in about four months. What if the rate drops before then?" (drafted)
- "Is there any way to fix today's rate for the payment I have to make in the autumn?" (drafted)
putting_off_booking: "I'll check it again tomorrow."
- What: The client had been about to book or fix a rate today, and says they will leave it until later (tomorrow, after the weekend) or spread it over the coming days.
- Not for: A client waiting for a better rate, who needs an alert instead; a client who has decided not to transfer at all; a client who has just booked.
- Applies: always
- Points:
offer_forward_for_known_future_payment.h1(core) [approved]: Do you still want to lock the rate in today? - Client examples:
- "I'm not really bothered about that tonight because it's it's getting a bit late here. So I'll check it tomorrow." (harvest
4079952215:19next, same call, earlier) - "I've got to ring, like, for the next four nights, it be Tuesday, Wednesday, Thursday, Friday, I'll do a £100,000 a night, but then Monday over there is a bank holiday, ain't it?" (harvest
4079952215:25prev, right before the line)
- "I'm not really bothered about that tonight because it's it's getting a bit late here. So I'll check it tomorrow." (harvest
offer_alert_or_market_order (Offer a rate alert or market order)
Flat lines left: offer_alert_or_market_order.2 (draft).
waiting_for_target_rate: "I'm waiting for the rate to go up."
- What: The client says they are waiting for the exchange rate to reach a level before booking, that the rate has been bad so they are holding off, or asks about rate alerts or market orders.
- Not for: A rate complaint or a request for a better price (a rate concern is open: never offer an alert then); a client with a payment due within days; a client who already has an alert at the level they want.
- Applies: always
- Points:
offer_alert_or_market_order.h1[approved]: Are you looking at setting a rate alert?offer_alert_or_market_order.1(core) [approved]: Rather than watching the screen, set a bookable alert at your target and it books or notifies you the moment it's hit.offer_alert_or_market_order.3[approved]: If you want it hands-off, a market order executes automatically when the rate is reached.
- Client examples:
- "I don't wanna draw it down until, really, until that exchange rate goes up." (harvest
3396094279:27next, other call) - "It's just, obviously, exchange rate's pretty been pretty bad. So I've been trying" (harvest
3417831457:9next, same call, earlier) - "Okay. Okay. So the target rate is the rate that I want to get that" (harvest
2995224421:17next, other call)
- "I don't wanna draw it down until, really, until that exchange rate goes up." (harvest
set_up_recurring_or_batch (Set up recurring or batch payments)
Flat lines left: none (set_up_recurring_or_batch.4 was deleted by COPILOT-095).
same_payments_every_month: "It's the same payment every month."
- What: The client pays the same person or account on a regular schedule (monthly rent, salaries, family support) and books each payment separately.
- Not for: A one-off transfer; several different payments made at the same time; a client who already uses saved beneficiaries or recurring alerts.
- Applies: always
- Points:
set_up_recurring_or_batch.1(core) [approved]: Your regular beneficiaries are saved, so each month it's a quote and two clicks; you don't re-enter anything.set_up_recurring_or_batch.3[approved]: Would it help to set a recurring alert so you're prompted before each payroll date?
- Client examples:
- "I pay my mum and the landlord every month and type the details in each time." (drafted)
- "Salaries go out on the same date every month, and I do each one by hand." (drafted)
- "Yeah. It'll be a monthly sort of thing or, you know, as I build up some cash." (harvest
3233880949:106next, other call)
several_payments_at_once: "I pay several suppliers at once."
- What: The client pays several different people or suppliers at the same time and books each payment one by one.
- Not for: One regular payment to the same person; a one-off transfer; a client who already uploads batches.
- Applies: always
- Points:
set_up_recurring_or_batch.2(core) [approved]: For the supplier run you can upload all the payments as one batch against a single trade. - Client examples:
- "I've got eight supplier invoices to pay this week. Do I have to book them one by one?" (drafted)
- "Every Friday we send payments to all our suppliers, each one separately." (drafted)
add_user_access (Add a colleague or approval step)
Flat lines left: add_user_access.3 (draft).
someone_else_books_payments: "My bookkeeper usually does the payments."
- What: The client mentions a colleague, bookkeeper, accountant or partner who books, prepares or needs to see their payments, or says they share their login.
- Not for: A client who wants a second person to approve payments before they go out; a sole user with no one else involved.
- Applies: always
- Points:
add_user_access.h1[approved]: I can add other people on there, if that would help.add_user_access.1(core) [approved]: You can add your bookkeeper with their own login and set exactly what they can do: quote, book, or add beneficiaries.
- Client examples:
- "My bookkeeper normally does the payments. Can she just use my login?" (drafted)
- "My business partner needs to be able to book them too." (drafted)
wants_a_second_approver: "Can someone else check payments before they go?"
- What: The client wants someone else to check or approve payments or new beneficiaries before they go out.
- Not for: A colleague who only needs their own login to book or view payments.
- Applies: always
- Points:
add_user_access.2(core) [approved]: If you'd like a second pair of eyes, payments and new beneficiaries can require approval from a second user before they go out. - Client examples:
- "I'd like someone to check the payments before they actually go out." (drafted)
- "Can we set it so two of us have to approve a new payee?" (drafted)
handle_rate_complaint (Handle a rate complaint)
Flat lines left: none.
qualify_the_quote: the rate situation, identical to onboarding (headline "Qualify the quote before you respond").no_quote_in_hand: the rate situation, identical to onboarding (headline "Can you do better than that?").competitor_named: the rate situation, identical to onboarding (headline "Company X gives me a better rate.").serial_shopper: the rate situation, identical to onboarding (headline "I'll just check what the others are doing.").mid_market_comparison: the rate situation, identical to onboarding (headline "Why am I getting less than Google says?").bank_matched: the rate situation, identical to onboarding (headline "I spoke to my bank; they matched you.").concession_terms: the rate situation, identical to onboarding (headline "If you do move on price").
handle_service_complaint (Acknowledge a service failure and fix the process)
Flat lines left: handle_service_complaint.1 (draft), handle_service_complaint.2 (draft), handle_service_complaint.3 (draft).
calling_back_about_a_complaint: "Is this about my email?"
- What: The rep is calling the client back about a complaint the client sent by email (usually about how long a payment took), and the call is at the greeting or the client has just asked what the call is about.
- Not for: A complaint the rep has already acknowledged; a client raising a new complaint for the first time on this call; a routine call with no complaint behind it.
- Applies: always
- Points:
handle_service_complaint.h1(core) [approved]: I just got your email and wanted to give you a quick call to cover any concerns; I understand you're not pleased with how long it took. - Client examples:
- "Good and you." (harvest
3400926772:3prev, right before the line) - "Hi, yes. Is this about the email I sent yesterday?" (drafted)
- "Good and you." (harvest
reengage_dormant_with_a_reason (Re-engage with a specific reason)
Flat lines left: reengage_dormant_with_a_reason.2 (draft).
not_traded_for_a_while: "I haven't used it in a while."
- What: The client has not traded for a long time, has no problem to report, and has not said why they stopped.
- Not for: An active client; a client who has said they have nothing planned; a client reporting a problem.
- Applies: always
- Points:
reengage_dormant_with_a_reason.1[approved]: You last transferred in {month}; has the need gone away, or is something waiting on the rate? (needs{month}fromlast_transfer_month)reengage_dormant_with_a_reason.3(core) [approved]: Is there anything about the platform or the process that put you off using it again?
- Client examples:
- "To be honest, I haven't used the account since last year." (drafted)
- "We just stopped using it after the last transfer, really." (drafted)
accept_no_need_gracefully (Accept there is no current need)
Flat lines left: accept_no_need_gracefully.2 (draft).
no_transfers_planned: "Nothing planned at the moment."
- What: The client says clearly that they have no transfers planned, or no need for the service, at the moment.
- Not for: A client who mentions any future payment, even vaguely; a client who has not yet been asked about upcoming payments.
- Applies: always
- Points:
accept_no_need_gracefully.1(core) [approved]: Understood. Your account stays open at no cost, and if anything comes up you can book online or call me.accept_no_need_gracefully.3[approved]: Thanks for your time; I'll leave you alone until you need us.
- Client examples:
- "We don't have anything planned at the moment." (drafted)
- "Honestly, I don't need to send anything for now." (drafted)
agree_next_step (Agree the next step)
Flat lines left: agree_next_step.1 (draft), agree_next_step.2 (draft), agree_next_step.3 (draft).
ready_to_book_after_a_fix: "I'll log on and do the trade now."
- What: Something that stopped the client booking (their login, two-factor authentication, account activation, or funds arriving) has just been fixed on this call, and the client says they will log in or book now.
- Not for: A client asking which delivery date to choose on the booking screen; a problem that is not fixed yet; a client asking where a payment they already booked is.
- Applies: always
- Points:
agree_next_step.h1(core) [approved]: You should be able to book the trade now. - Client examples:
- "But what I'm gonna do now is just log on and then try to reset up the two factor authentication and do the trade that I wanted to do." (harvest
3705848894:48prev, same call, earlier) - "Well, I'll try it first of all, but I'll have to call you back if I fail miserably." (harvest
3683015217:117next, same call, earlier)
- "But what I'm gonna do now is just log on and then try to reset up the two factor authentication and do the trade that I wanted to do." (harvest
choosing_a_delivery_date: "Which delivery date do I pick?"
- What: The client asks about the delivery date of a transfer they are booking or about to book: which date to choose, whether the date makes a difference, why a date is not available, or whether it can go today.
- Not for: Anything that is not about the date field while booking: a login or two-factor problem, where a booked payment is, a document request, the rate, or wrapping up once an issue is fixed. A client whose issue has nothing to do with delivery dates never gets this line.
- Applies: always
- Points:
agree_next_step.h2(core) [approved]: You should have the delivery date; just choose the next day that's available. - Client examples:
- "Oh, okay. Okay. So I have to request for Monday. Right?" (harvest
3234731385:30prev, right before the line) - "Delivery date. Does it make a difference?" (harvest
3546763352:116prev, other call) - "to be quick. Please remind me how does it start? That's in the website." (harvest
4079849881:33prev, same call, earlier)
- "Oh, okay. Okay. So I have to request for Monday. Right?" (harvest