Banking / FinTechAI Agents Product build: chat → Temporal rules

Conversational Rules Engine for Crypto↔Fiat Banking

Users set salary-day and balance rules in chat; Temporal workflows execute convert → transfer recipes with confirm cards and zero double-pays on webhook retries.

Rule setup time
Support / manual ops
2–4 min in chat + confirm
Duplicate payday executions
Seen on webhook retries
0 with event-keyed ids
Self-serve automations live
Near-zero
Salary + threshold rules in prod

The Problem

A banking app offered crypto↔fiat conversion and payouts, but automation lived in brittle crons and support macros. Users wanted to say “when salary hits, convert and pay rent” and have it actually fire once, every payday, without engineering tickets.

The Solution

We split Query vs Workflow agents, turned confirmed chat into Temporal RuleWorkflows, and bound salary / threshold triggers to Signals with idempotent Activities for convert, transfer, and notify steps.

Product surface

Chat could answer balances and quotes (Query agent) or create durable automations (Workflow agent): salary credit → convert a share to crypto → pay fixed fiat payees → park remainder, with abort guards on minimum balance.

Why Query vs Workflow

A single mega-agent mixed “what’s my balance?” with money movement tools and occasionally proposed transfers users never asked for. Splitting read-only Query from rule-authoring Workflow cut accidental side effects and kept confirm-card UX mandatory for any Temporal write.

Trigger → execute

Salary webhooks and balance threshold events start a short-lived RuleRunWorkflow (or Signal a supervisor that spawns one). Activities use ruleId + triggerEventId + stepIndex as idempotency keys so duplicate bank webhooks cannot double-convert or double-pay.

Rules as DSL + Temporal (with limits)

Each confirmed rule is a typed DSL document in the DB plus Temporal durable execution, not LLM memory. We use short RuleRunWorkflows per firing and Continue-As-New on any long-lived supervisor so we stay under Temporal’s ~51k event / ~50MB history hard limits. Blobs never go in Activity results; only ids.

Trust UX

Every new or edited rule rendered as a plain-language card (trigger, steps, caps, abort conditions) before commit. Edit and pause were first-class chat intents that mutated Temporal state. The LLM did not “remember” to run next month.

Platform MCP for the next product

Beyond southbound tools into the ledger and conversion rail, we exposed the banking product itself as a northbound MCP server (get_balances, quote_convert, preview_salary_recipe, create_rule, pause_rule) so a future wealth or goals product could call the same Temporal-backed money path with scoped tokens, instead of re-integrating core banking.

Production hardening

Multi-step recipes handle partial failure (convert OK / transfer fail) with pause + support playbooks; in-flight pause is cooperative between steps; step-up auth on first/large money rules; payee screening and FX slippage caps live in Activities/DSL; webhooks are signed with replay windows; runs emit receipts (rule version + ledger ids) for support, not Temporal UI alone.

Business Impact

Payday recipes became a product surface, not a backlog item. Users author rules in natural language; Temporal owns waiting, retries, and replay when support asks “why did rent send?” Platform MCP means the next product plugs into the same money path instead of forking it.

Technical architecture write-up

Tech Stack

Conversational UIQuery agent + Workflow agentVercel AI SDK / tool callingTemporal workflows + SignalsCrypto↔fiat conversion railsLedger / payee APIsPlatform MCP serverIdempotent Activities

Case FAQs

Could the chat move money without confirmation?

No. Workflow agent only persisted rules after the user confirmed the rule card. One-shot “run now” also required explicit confirm. Query agent stayed read-only or dry-run.

Is every rule a Temporal workflow?

Each rule is a typed DSL record plus Temporal execution. We do not keep one immortal history forever: each payday/trigger is typically a short RuleRunWorkflow; supervisors Continue-As-New before Temporal’s history limits (~51k events / ~50MB).

What if convert succeeds but the rent transfer fails?

The run marks PARTIAL, keeps a ledger-linked receipt, and follows a compensation / support playbook. It does not blindly re-run the convert step. The user can be notified; the rule can optionally auto-pause.

What if salary webhook arrives twice?

Ingress verifies signatures and a replay window, dedupes on provider eventId, then Activities key on the credit event id. The second delivery is a no-op.

Can another product use these banking capabilities?

Yes: that is the platform MCP design. Product B connects as an MCP client with scoped auth; create_rule and convert paths still hit the same Temporal Activities and policies. Partners never receive raw ledger credentials.

Is this the same as the mid-market banking ops case study?

Same Temporal + agent discipline, different buyer: this is consumer/fintech product automation. The mid-market case study is maker-checker ops for KYC and payment repairs inside a bank.

Want a system like this?

Tell us the workflow. We reply with a short architecture brief: stack, gates, and timeline.