TRACK 1 Built for the Airwallex Agentic Banking Hackathon

The treasury agent that knows when to stop.

Five bills. Three currencies. 72 hours. Cash for 60% of it. Treasury Controller funds, converts, defers and escalates (each for a stated reason), adapts when the evidence changes, and never plans through your reserve floor.

Runs on a mock sandbox with demo money. No sign-up needed.

python3 demo.py --yes
0
obligations triaged in a 72-hour window
0
currencies: USD, EUR, GBP
0
tests across rules, controls & failure paths
0
payments the model can authorize on its own
Triage

Four decisions. Four different reasons.

Needs ≈ USD 47,784. Cash above the floor ≈ USD 28,043. The agent can't pay everything, so it ranks by consequence and writes every call down with the rule that made it.

FUND

Shipping & rent

USD 8,500 · USD 6,000

Non-payment stops operations; rent is fixed and non-negotiable. Funded first from cash above the floor.

R1_FUND_OPERATIONS_CRITICAL · R2_FUND_FIXED
CONVERT

German supplier

EUR 12,000

Buys only the minimum: 12,000 + 12.85 SWIFT fee − 500 already held = EUR 11,512.85. Not a cent more.

R3_CONVERT_MINIMUM
DEFER

Software licenses

USD 1,200

The plan is USD 691.45 short. A zero-penalty bill is the cheapest one to push. Re-funded the moment cash arrives.

R4_DEFER_CHEAPEST
ESCALATE

Contractor payout

GBP 15,000 ≈ USD 19,050

Breaches the USD 15,000 single-payment threshold, so it goes to a human. The agent will never split a payment to sneak under a limit.

R5_ESCALATE_THRESHOLD

The reserve floor is a hard line.

Planning never draws below it. Execution re-checks it against the actual FX quote, net of every other commitment.

headroom after plan USD 0.00
committed USD 26,991.45 free headroom USD 508.55 floor USD 10,000.00
Adaptive

It changes its mind for the right reasons.

Plans go stale the moment the world moves. Treasury Controller re-reads the evidence and tightens or loosens its own autonomy, recalculating only the decisions that cash or confidence was actually blocking.

act 1 · triage
Receipt confidence
0.92
Autonomous FX limit
USD 15,000
Architecture

Policy lives in code. Judgment lives in the model.

The model reads messy human input and explains exceptions to approvers. It never touches an amount, a limit or a credential. A test asserts no threshold appears in any prompt.

● The model

Reads and explains.

Text in, text out. No tools, no banking credentials, no authority.

  • Reads the customer email into a typed signal, e.g. stance=delay, delay_days=14, with a verbatim quote as evidence.
  • Writes plain-English notes for approvers, discarded if they cite any figure not in the facts.
  • Swappable: Claude, any OpenAI-compatible endpoint, or a deterministic reader. Decisions are identical either way.
● The code

Owns every number.

Pure-function rules, a state machine and a hardened ledger.

  • Amounts, limits, reserve floor, validations, duplicate checks and every state transition.
  • Confidence tiers map to autonomy: 0.92 → USD 15,000; 0.37 → USD 2,500.
  • Reconciles ledger deltas against Airwallex after every read; any unexplained movement halts the agent.
Prompt-injection proof by construction. An email can only lower confidence, never raise it. A malicious message can make the agent more cautious, but never more powerful.
Controls

Built like money is actually moving.

Every control below is enforced in code and covered by the test suite.

Tamper-evident audit chain

Append-only, HMAC-SHA256 hash-chained with a key held outside the database. Triggers refuse UPDATE and DELETE. Rewrite one settled amount and verification breaks.

a41f…9ctriage.plan · R1 FUND #1 USD 8,500←0e7d
7b02…e1email.signal · delay 14d · conf 0.37←a41f
c9d8…42approval.signed · apr_c247 · dana.controller←7b02
f310…7afx.converted · EUR 11,512.85←c9d8
$ manage.py verify-audit → chain OK · 4/4 links verified

Digest-bound approval cards

A SHA-256 digest of the action, amount, counterparty, destination, sell ceiling, evidence and expiry. Single use, 24h expiry, superseded when evidence changes.

APPROVAL REQUIRED · POLICY_EXCEPTION · code EDE7A837
GBP 15,000.00 → Harper & Lowe Engineering Ltd

Segregation of duties

Treasury approver, finance controller and compliance roles. The requester can never approve, nobody enrols themselves, and five failed passcodes lock the account.

Never pays twice

A UUID request_id is persisted before every write. Timeouts are treated as ambiguous and looked up, never blindly retried.

Pinned payees & screening

Bank details are pinned by keyed fingerprint. Every payee is screened at triage, before conversion and before payout.

Locked-down endpoint

Credentials go to a known Airwallex host only. Production is refused by default. No full IBAN ever touches disk.

Live demo

Watch it triage in real time.

Watch the walkthrough, then drive it yourself. All four acts end to end: triage, the confidence drop, the deposit, and a human-signed FX conversion and transfer.

98-81-148-190.sslip.io
USD37,500.00confidence0.92
01 Triage02 Email shock03 Deposit04 Execute
Live now

Run the controller yourself.

The full dashboard runs on the same agent as the CLI: obligations, cash against the floor, forecast confidence, approval cards and the event log.

  1. 1
    Click Run Act 1 · Triage and watch the agent plan.
  2. 2
    Fire the email shock and the deposit. Confidence and limits react.
  3. 3
    Sign in as a demo approver below and type the card's code to execute.
Demo approversdemo money only
sam.treasuryTreasury · signs FX conversions
fx-approve-42
dana.controllerFinance Controller · policy exceptions & failed payouts
release-funds-7
casey.complianceCompliance · screening reviews
screen-names-11
Segregation of duties is live: the requester can't approve, and each card needs the right role.
Open the live dashboard
Run it

Zero dependencies. Zero credentials.

The runtime is the Python standard library. An offline mock of the Airwallex sandbox ships in the repo, so the whole four-act scenario runs on your laptop in seconds.

01

Offline: the demo runs against a local mock that enforces the sandbox's documented fees, single-use quotes and error codes.

02

Sandbox: drop your Airwallex client ID and API key into .env, generate an audit key, and run --live.

03

Model optional: add an Anthropic or OpenAI-compatible key for richer email reading. The decisions don't change.

bash
# clone and run the four-act demo offline
git clone https://github.com/coldrazer/treasury-controller
cd treasury-controller
python3 demo.py --yes

# run the test suite
python3 -m venv .venv && .venv/bin/pip install -r requirements-dev.txt
.venv/bin/python -m pytest

# against the real Airwallex sandbox
cp .env.example .env && chmod 600 .env
python3 manage.py gen-key
python3 smoke_live.py
python3 demo.py --live
Open source · MIT

Autonomy you can audit.

Read the rules, run the demo, try to break the chain. Every decision has a reason, and every reason is in the log.