Composite study

This is a product-class write-up, not a named-client story and not a results press release. Counts below describe the pack we actually write (approach points, tools, layers) — not invented bug totals or conversion lifts.

4
Approach points
5
Tools in the pack
5
Layers covered
3
Challenges documented

Overview

The copilot summarized spend well on demo accounts. On staging with pending authorizations, multi-currency cards, and overdraft buffers, it quoted a cash figure that was not the ledger balance.

Worse: “You’re good to go” on a credit-limit question read as approval. Support then had to unwind customer expectations.

Industry pattern this is grounded in

Customer-facing financial assistants inherit the same liability pattern as policy chatbots: a confident wrong number is an operational and regulatory incident, not a copy issue.

Highlights

Typical launch bar: Block until pass rules hold on the money, identity, or safety path.

Challenges

01

Pending vs posted vs available were three numbers; the prompt used the word “balance” for all of them.

02

The model rounded FX in prose and disagreed with the statement PDF.

03

Sandbox banks delayed webhooks; the copilot filled the gap with a guess instead of “balance not yet updated.”

How we tested

01

Every money figure must come from a tool call, displayed with as-of time, not from model memory.

02

Forbidden language list: approved, guaranteed, waived, you can spend. Those require the real decisioning API or a refuse.

03

Idempotent transfer and IDOR on account ids sit in the same sprint as the evals — UI hide is not authorization.

04

Support impersonation must be scoped and audited; the copilot must not see another customer’s ledger because a ticket id was pasted.

Starting point vs what we required

Starting point versus the controls we required
Starting pointWhat we required
Pending vs posted vs available were three numbers; the prompt used the word “balance” for all of them.Every money figure must come from a tool call, displayed with as-of time, not from model memory.
The model rounded FX in prose and disagreed with the statement PDF.Forbidden language list: approved, guaranteed, waived, you can spend. Those require the real decisioning API or a refuse.
Sandbox banks delayed webhooks; the copilot filled the gap with a guess instead of “balance not yet updated.”Idempotent transfer and IDOR on account ids sit in the same sprint as the evals — UI hide is not authorization.

What we delivered

01

LLM traces / evals

  • LangSmith — Prove amounts came from the balances API
02

API / contract

  • Postman — IDOR and idempotent transfers
03

Journeys / UI

  • Playwright — Transfer, statement, copilot side-by-side
04

Adversarial evals

  • Promptfoo — Approval-language and social-engineering prompts
05

Load / soak

  • k6 — Payday-window transfer latency without silent queue drop

Outcomes

We required structured tool output for amounts. Free-text numeric claims without a matching tool trace failed the eval.

Postman: same idempotency key twice equals one movement; user A cannot transfer from account B. Those stayed in the launch pack.

Stack

Testing stack used on this product class
LayerToolWhat we validated
LLM traces / evalsLangSmithProve amounts came from the balances API
API / contractPostmanIDOR and idempotent transfers
Journeys / UIPlaywrightTransfer, statement, copilot side-by-side
Adversarial evalsPromptfooApproval-language and social-engineering prompts
Load / soakk6Payday-window transfer latency without silent queue drop

Same method as the rest of our work: severity-ranked findings, pass rules in writing, and a ship / wait / block call. See the evaluation method and tool comparison.