{"schema_version":"1","site":"https://decosa.ai","id":"bank-change-check","num":"157","name":"Vendor bank-change check","tool_name":"Check a bank-detail change before you pay","short":"Bank-change check","blurb":"For AP clerks, controllers and the bookkeepers who pay vendors for clients. Forward the email that asks to change a vendor's bank details, with your vendor file. It lists the warning signs with their evidence: a look-alike domain, replies routed elsewhere, failed sender checks, a sender who isn't on file, a new phone number, a bank in another country, an account holder who isn't the vendor, pressure, secrecy, \"don't call\". It always says to hold the change and call the number already on file, never the one in the email, because a real vendor's hacked mailbox passes every check the email allows. You record the call-back and a second person approves, in a signed record. It never says an email is safe and never releases or blocks a payment.","status":"preview","labels":{"industry":["finance","compliance-trust"],"job":["review","attest"],"input":["text"],"deploy":["selfhost"],"status":"preview","output":["record","data"],"data":["confidential"],"hardware":"gpu-96","licence":"permissive"},"industries":["finance","compliance-trust"],"runs_in":["selfhost"],"part_of":[],"built_from":["signed-record"],"models":"Qwen3.8-27B (quotes the pressure and secrecy signs; the header, domain and bank checks are code)","where":"Hosted demo on made-up emails; self-host or confidential access for your real AP inbox","hardware":"1x RTX PRO 6000 (96 GB) for Qwen3.8-27B; the header and vendor-file checks run on CPU","final_artifact":"Warning signs with evidence, the call-back plan to the number on file, and a signed record with the call-back and a second approver.","self_host_first":true,"verification":{"receipt_coverage":"full","summary":"Header and vendor-file checks in code; every model sign quoted from the email; receipt per model call; signed check and call-back records","manual_qa":{"hosted":{"date":"2026-09-29","result":"pass","p50_ms":8100,"p95_ms":18900,"runs":19,"receipts_per_run":1,"cost_per_run_usd":0.00053},"selfhost":null,"known_limits":["Hosted verification ran on our pre-release server through the production gateway, before these routes reached the production API.","Measured on 64 synthetic emails written by one author; real business email compromise is messier.","A calm email from a real vendor's hacked mailbox that keeps the same bank country passes every check in the email; only the call-back catches it.","No domain age, ownership or account-validation look-ups (nothing leaves the box by design)."],"nightly_covers":null},"nightly":"https://api.decosa.ai/verify/status"},"eval_summary":{"metrics":[{"name":"Fraud flagged (score 3 or more)","value":"9 of 9","unit":null,"n":9,"split":"test","note":"Wilson 95% CI 0.70-1.00; dev 21 of 21"},{"name":"Genuine changes flagged","value":"0 of 8","unit":null,"n":8,"split":"test","note":"dev 0 of 18"},{"name":"Bank-change requests detected","value":"19 of 19","unit":null,"n":19,"split":"test","note":"dev 45 of 45"},{"name":"Content signs found: open model vs keyword rules","value":"43 of 47 vs 23 of 47","unit":null,"n":47,"split":"synthetic","note":"dev and test together; precision 0.83 vs 0.88"},{"name":"Verdicts calling an email safe","value":"0","unit":null,"n":64,"split":"synthetic","note":null}],"dataset":"64 synthetic emails (30 fraud, 26 genuine, 8 with no bank change; 6 not in English) and a 26-vendor file, written blind by a separate author; stratified split, dev 45, test 19.","held_out":true,"caveats":["Synthetic emails from one author; real BEC mail is messier.","Small test set (9 frauds, 8 genuine changes): wide confidence intervals.","Code signs were tuned on the dev set.","A hacked real mailbox writing calmly passes every check in the email; the call-back is the control."],"date":"2026-09-29","doc_url":"https://decosa.ai/metrics/evals/bank-change-check"},"stack":{"summary":"For AP clerks, controllers and bookkeepers. It reads the email (headers included) against your own vendor file and lists the warning signs: a look-alike domain, replies routed elsewhere, failed sender checks, a sender who isn't on file, a new phone number, a bank in another country, an account holder who isn't the vendor, pressure, secrecy, \"don't call\". It always says to hold the change and call the number on file, and records the call-back and a second approver in a signed record. It never says an email is safe and never releases or blocks a payment.","tagline":"An email asks to change a vendor's bank details: the warning signs with their evidence, the call-back to the number already on file, and a signed record with a second approver.","deployment":"self-host-first","regulatory_note":"Nacha Operating Rules, 2024 risk-management amendments (nacha.org rule pages read 29 Sep 2026): non-consumer Originators must have risk-based processes and procedures reasonably intended to identify ACH entries initiated due to fraud, including entries authorized under False Pretenses (\"the inducement of a payment by a Person misrepresenting ... that Person's identity\"), reviewed at least annually. Phase 1 from 20 Mar 2026 (ODFIs and originators with 6 million or more ACH entries in 2023); Phase 2 from 19 Jun 2026 (all other non-consumer originators). The signed call-back record documents one such step; it is not a compliance determination, and this is not legal advice.","components":[{"id":"llm","role":"Reads the email's text and quotes the pressure, secrecy, 'don't call' and redirected-payment signs, and reads the new account's bank and holder; the header, domain and vendor-file checks are code","name":"Qwen3.8-27B (NVIDIA NVFP4)","hf_repo":"nvidia/Qwen3.8-27B-NVFP4","license":"Apache-2.0","params":"27.8B","quant":"NVFP4 (MLP) + FP8 (attention/GDN), FP8 KV cache, MTP speculative decoding k=3","vram_gb":57,"memory_gb_estimate":null,"engine":"vLLM 0.29.0","receipt_coverage":"strong","in_hosted_demo":true,"tiers":["standard"],"alternative_to":null},{"id":"llm-lite","role":"Lite tier: the same quoted reading on a 48 GB card","name":"Gemma 4 26B A4B (instruction-tuned)","hf_repo":"google/gemma-4-26B-A4B-it","license":"Apache-2.0 (model card also links the Gemma 4 licence page)","params":"25.2B","quant":"BF16 weights; FP8 at load time (vLLM --quantization fp8) to fit a 48 GB card","vram_gb":null,"memory_gb_estimate":null,"engine":"vLLM 0.29.0 (Gemma4ForConditionalGeneration is in its model registry)","receipt_coverage":"none","in_hosted_demo":false,"tiers":["lite"],"alternative_to":null},{"id":"llm-best","role":"Best tier: a larger model for long, forwarded email threads","name":"DeepSeek-V4-Flash (NVIDIA NVFP4)","hf_repo":"nvidia/DeepSeek-V4-Flash-NVFP4","license":"MIT","params":"284B","quant":"NVFP4 experts + FP8 (about 159-176 GB of weights)","vram_gb":192,"memory_gb_estimate":null,"engine":"vLLM B12X community build, TP2 on 2x RTX PRO 6000, MTP draft fixed by the kit's patches","receipt_coverage":"none","in_hosted_demo":false,"tiers":["best"],"alternative_to":null},{"id":"glm-wanted","role":"Second judge, from another family","name":"GLM-5.3-Flash","hf_repo":"zai-org/GLM-5.3-Flash","license":"MIT","params":"321B","quant":"NVFP4 on NVIDIA (nvidia/GLM-5.3-Flash-NVFP4, about 170-186 GB, unconfirmed); MLX 4-bit on a Mac (165 GB)","vram_gb":null,"memory_gb_estimate":170,"engine":"SGLang SM120 build, TP2 on 2x 96 GB (vLLM is broken on sm_120 for this model, and the SGLang build hung on our server), or mlx-lm on a Mac with 192 GB or more","receipt_coverage":"none","in_hosted_demo":false,"tiers":["wanted"],"alternative_to":null}],"tiers":[{"id":"lite","label":"Lite · one 48 GB card","summary":"The same pipeline on a smaller mixture-of-experts model. Faster and cheaper; accuracy on this task unknown.","components":["llm-lite"],"hardware":"1x L40S or RTX 6000 Ada 48 GB (not measured)","quality_evidence":[{"metric":"accuracy on this task","value":"not measured yet","source":null}],"latency_note":"not measured yet","in_hosted_demo":false,"receipt_coverage":"partial","receipt_note":"Direct route: calls are attested by the box's key; no gateway receipts.","hosting":null},{"id":"standard","label":"Standard · the hosted demo, one 96 GB card","summary":"Qwen3.8-27B quotes the content signs; the header, domain and vendor-file checks and the call-back plan are code. One model call per email, receipted.","components":["llm"],"hardware":"1x RTX PRO 6000 Blackwell 96 GB","quality_evidence":[{"metric":"fraud flagged / genuine changes flagged, held-out test (19 emails, gateway, run once)","value":"9 of 9 / 0 of 8","source":"decosa-api docs/evals/bank-change-check.md, measured on our server 2026-09-29, gateway route"},{"metric":"content signs found, open model vs keyword rules (all 64 emails)","value":"43 of 47 vs 23 of 47","source":"decosa-api docs/evals/bank-change-check.md, dev and test together"}],"latency_note":"measured: seconds per email on the shared gateway under load (test set), longer at the slow end","in_hosted_demo":true,"receipt_coverage":"strong","receipt_note":"Hosted: gateway-signed receipt per model call. Self-hosted: attested by the box's key.","hosting":null},{"id":"best","label":"Best · DeepSeek-V4-Flash on two more cards","summary":"A larger model for long, multi-claimant files.","components":["llm-best"],"hardware":"2x RTX PRO 6000 96 GB","quality_evidence":[{"metric":"accuracy on this task","value":"not measured yet","source":null}],"latency_note":"not measured yet","in_hosted_demo":false,"receipt_coverage":"partial","receipt_note":"Not a hosted model: calls are attested by the box's key only.","hosting":null},{"id":"wanted","label":"Wanted · two large judges from different families","summary":"DeepSeek-V4-Flash and GLM-5.3-Flash each read the file, and a finding stands when they agree; disagreements go to the reviewer. Claim files stay on your own hardware, never on community providers. Not served yet.","components":["llm-best","glm-wanted"],"hardware":"Your own hardware: 2x 96 GB cards for DeepSeek-V4-Flash plus 2x 96 GB for GLM-5.3-Flash, or one Mac Studio with 512 GB holding both 4-bit builds (156 + 165 GB, sizes from our Mac; not run together yet). Estimate.","quality_evidence":[{"metric":"accuracy on this task","value":"not measured yet","source":null}],"latency_note":"not measured yet","in_hosted_demo":false,"receipt_coverage":"none","receipt_note":"On your own hardware its calls are attested by the box's key only: not a hosted model there, so no gateway receipts. Never sent to community providers.","hosting":"own-hardware"}],"alternates":[],"services":[{"name":"decosa-api","port":8445,"image":"${DECOSA_REGISTRY}/decosa-api:0.1.0","purpose":"Email parsing, the header and vendor-file checks, the call-back plan, signing and the HTTP API (/bank-change/*). No GPU. Binds 127.0.0.1 by default."},{"name":"decosa-llm","port":8000,"image":"${DECOSA_REGISTRY}/decosa-llm:0.1.0","purpose":"vLLM OpenAI endpoint for Qwen3.8-27B. Internal to the compose network."}],"tools":[{"name":"Nacha: Risk Management Topics, Fraud Monitoring Phase 2","url":"https://www.nacha.org/rules/risk-management-topics-fraud-monitoring-phase-2","license":"Nacha publication (summarised, quoted briefly)","purpose":"The effective dates and the False Pretenses definition the record cites."},{"name":"decosa record (vertical 07) and POST /record/verify","url":"https://decosa.ai/apps/record","license":"AGPL-3.0-or-later (decosa-api)","purpose":"The hash chain and the Ed25519-signed record; anyone can re-check it."}],"hardware":[{"tier":"1x RTX PRO 6000 Blackwell 96 GB","fits":true,"notes":"Measured: the hosted demo's Qwen3.8-27B runs on one of these cards on our server."},{"tier":"1x L40S / RTX 6000 Ada 48 GB","fits":null,"notes":"Not measured. FP8 Qwen3.8-27B with a shorter context, or Gemma 4 26B A4B (lite)."},{"tier":"CPU only","fits":true,"notes":"The date rules, the sums, the header checks, signing and verification need no GPU; reading the text needs the model."}],"latency":[{"lane":"one email, busy shared gateway","typical_ms":8100,"source":"decosa-api docs/evals/bank-change-check.md, measured on our server 2026-09-29, gateway route, test set p50 (p95 18.9 s)"},{"lane":"one email, keyword rules only (no model)","typical_ms":20,"source":"decosa-api docs/evals/bank-change-check.md, measured on our server 2026-09-29, gateway route, rules mode"}],"benchmark":null,"notes":[]},"buyer_facts":[{"label":"What it checks","value":"Sender, Reply-To and Return-Path against your vendor file; SPF, DKIM and DMARC results; look-alike domains; phone numbers and addresses not on file; the new bank's country (IBAN, SWIFT) and account holder against the vendor; pressure, secrecy, \"don't call\" and redirected payments, quoted."},{"label":"What it never does","value":"It never says an email is safe, never edits your vendor file, and never releases, blocks or schedules a payment. The call-back must go to the number on file; the record refuses any other number. A confirmed change needs the vendor's last 4 digits of the new account: if they differ from the email, it is signed as \"details differ\" and stays on hold. The second approver's name must differ from the caller's; that is a name check only (it catches the same name written another way, such as initials, word order or an email address, not two people who sign for each other)."},{"label":"Data retention","value":"Nothing kept on the server: the email and vendor file live in memory for the request; logs carry counts only. You keep the signed records."},{"label":"What leaves the box (hosted demo)","value":"The email text goes to Qwen3.8-27B through the Decosa API, whose receipts hold hashes, not text. No domain look-ups are made. Self-hosted, nothing leaves. The hosted demo is for made-up emails."},{"label":"Model calls per email","value":"One (none in rules-only mode)."},{"label":"Cost per email","value":"A fraction of a cent per email on average at the gateway list price (held-out test). Each run shows its own measured cost."},{"label":"Also used in","value":"Vendor onboarding (HR and procurement): a new vendor's first bank details go through the same check and call-back."}],"hosted_now":{"needs":["qwen3.8-27b"],"off":[],"live_by_default":true,"live_status":"https://api.decosa.ai/status"},"data_handling":{"page":"/data#bank-change-check","self_host":{"level":"confidential","leaves":"nothing","summary":"Runs on your machine; nothing is sent to Decosa or a third party by default."},"hosted":{"level":"operator-processed","demo_only":true,"summary":"Hosted demo on sample or public data only; self-host for real data.","gpus":"operator-contracted","third_parties":[],"retention":"Nothing kept on the server: the email and vendor file live in memory for the request; logs carry counts only. You keep the signed records.","used_for_training":false,"encrypted_while_processed":false},"sealed_tier":{"applies":false,"note":"The sealed tier (raw chat only, never use-case pipelines) is paused at launch (/docs/sealed-tier)."},"external_calls":[]},"console":{"href":"/tools/finance/bank-change-check","input":"chat","lanes":[{"id":"signs","title":"Warning signs","kind":"list"},{"id":"callback","title":"Call back","kind":"list"},{"id":"record","title":"Signed record","kind":"json"}],"samples":[{"n":1,"id":"lookalike-urgent","title":"Lookalike urgent","deep_link":"/tools/finance/bank-change-check?sample=1&autorun=0"},{"n":2,"id":"misspelled-domain-urgent","title":"Misspelled domain urgent","deep_link":"/tools/finance/bank-change-check?sample=2&autorun=0"},{"n":3,"id":"calm-tld-swap","title":"Calm tld swap","deep_link":"/tools/finance/bank-change-check?sample=3&autorun=0"},{"n":4,"id":"real-mailbox-redirect","title":"Real mailbox redirect","deep_link":"/tools/finance/bank-change-check?sample=4&autorun=0"},{"n":5,"id":"genuine-bank-acquisition","title":"Genuine bank acquisition","deep_link":"/tools/finance/bank-change-check?sample=5&autorun=0"},{"n":6,"id":"genuine-german-merger","title":"Genuine german merger","deep_link":"/tools/finance/bank-change-check?sample=6&autorun=0"},{"n":7,"id":"no-change-phishing","title":"No change phishing","deep_link":"/tools/finance/bank-change-check?sample=7&autorun=0"}],"deep_link_params":{"sample":"1-based index into samples, or a sample id","autorun":"1 = start the run once the sample is loaded; 0 (default) = only preselect","reduce-motion":"1 = turn off animations"}},"api":{"base":"https://api.decosa.ai","contract":"/api/contract.json","contract_markdown":"/api/contract.md","reference":"/docs/api","keys":"/account/keys"},"prompts":{"hosted":"/prompts/bank-change-check-hosted.md","selfhost":"/prompts/bank-change-check-selfhost.md","assemble":"/prompts/bank-change-check-assemble.md","mac":null},"rehearsal":{"bundle":"/samples/bank-change-check.zip","bundle_url":"https://decosa.ai/samples/bank-change-check.zip","folder":"/samples/bank-change-check/","expected":"/samples/bank-change-check/expected.json","files":["/samples/bank-change-check/expected.json","/samples/bank-change-check/inputs/email.eml","/samples/bank-change-check/inputs/vendors.csv"],"bytes":4471,"checks":["the bank-detail change is detected","the look-alike domain is flagged in code","the Hong Kong account is flagged against the vendor's country","the call-back names the number on file","the number in the email is listed as one not to use","the signed record verifies","a record with its warning-sign count changed no longer verifies","the model call has a signed receipt"],"licence":"Synthetic: the company, vendors, people, domains (.example) and accounts are invented. Part of decosa-api.","about":"A synthetic email from a look-alike of a made-up supplier's domain, with a free-mail Reply-To, a failed DMARC check, urgency, secrecy, 'don't call' and a Hong Kong account in another company's name, checked against a made-up vendor file. The change must be detected, the code signs flagged, the call-back must name the number on file (not the one in the email), and the signed record must verify.","run":{"containers":"docker compose exec api python scripts/rehearse.py bank-change-check","checkout":"python scripts/rehearse.py bank-change-check --bundle bank-change-check.zip --base-url http://127.0.0.1:8445","mac":".venv/bin/python scripts/rehearse.py bank-change-check"},"guidance":"Set up with a coding agent (we recommend Claude Code with Claude Opus 5.5; any capable coding agent works) on mock data only, run the rehearsal until every check passes, then run your own data locally yourself. Never give the agent real data during setup."},"hardware_fit":{"check":"/self-host/hardware?use=bank-change-check","data":"/api/hardware.json","tiers":[{"id":"lite","gpu_gb":40,"basis":"estimate","unknown":[]},{"id":"standard","gpu_gb":57.6,"basis":"stack","unknown":[]},{"id":"best","gpu_gb":192,"basis":"stack","unknown":[]},{"id":"wanted","gpu_gb":384,"basis":"estimate","unknown":[]}],"mac":null},"links":{"page":"/tools/finance/bank-change-check","json":"/use-cases/bank-change-check.json","metrics":"/metrics/bank-change-check","console":"/tools/finance/bank-change-check","console_sample":"/tools/finance/bank-change-check?sample=1&autorun=0","stack":"/tools/finance/bank-change-check#stack","try_live":"/tools/finance/bank-change-check","watch":"/tools/finance/bank-change-check","build":"/tools/finance/bank-change-check#build","self_host":"/tools/finance/bank-change-check#self-host","prompts":{"hosted":"/prompts/bank-change-check-hosted.md","selfhost":"/prompts/bank-change-check-selfhost.md","assemble":"/prompts/bank-change-check-assemble.md","mac":null}}}