Vasooli
For reviewers and mentors

Start here

Vasooli chases overdue B2B invoices on a bounded, auditable schedule. It works out why each invoice is unpaid, writes a reminder in a tone that matches, stops the moment a customer promises to pay or disputes the bill, and stops permanently the moment money actually arrives — confirmed by a signed Razorpay webhook, never by a model's opinion.

The claim worth testing

The AI cannot touch money

A language model reads customer replies and drafts reminder copy. It cannot mark an invoice paid, change an amount, pause recovery, or send anything — not because the prompt asks it not to, but because the code it would need is unreachable from the AI layer. That boundary is enforced by a test that parses the import graph and fails the build if it is ever crossed.

Where to verify it
  • backend/tests/architecture/test_layering.py
  • backend/tests/integration/test_disputes.py
  • backend/app/policy/disputes.py

The first proves the AI layer cannot import a mailer, a database session, or the payment client. The second asserts that when recovery pauses, the pause is attributed to the policy engine and the reading to the AI — two separate actors in the audit trail. The third is the decision itself: a pure function, no model involved.

Honesty

What is real, and what is not

Payment links, reconciliation, webhooksReal Razorpay — test mode
Reminder emailsReal, sent through Resend from this domain
Customer repliesReal inbound email, signature-verified
Reason diagnosis, reply reading, draftingReal Gemini, with deterministic fallbacks
RecipientsRedirected to the operator inbox, not customers
The ledgerEight seeded demo invoices, not real merchants

The amber bar at the top of every dashboard page reports these modes live. It turns red if the system is ever pointed at real customers or live payment keys.

Two minutes

Where to click

  1. 1
    Open the recovery queueEvery row answers “why is this happening?” in one sentence — no need to open anything to understand the state of the ledger.
  2. 2
    Open the invoice marked DisputedThis is the one worth seeing. Recovery is paused, and the card shows the customer’s own words beside the AI’s reading of them, the claims it extracted, and how confident it was.
  3. 3
    Scroll to the conversationEvery reminder, reply, AI reading, policy decision and payment event in order — colour-coded by who acted.
  4. 4
    Open the audit logAppend-only, enforced by a database trigger rather than convention. Nothing in the application can edit or delete a row.

Safe to explore. Reviewer accounts are read-only at the framework level — they cannot run a cycle, resolve a dispute, or send an email, whatever they click. If you were given an operator account instead, the grey Dry run button evaluates the whole cadence and sends nothing.

Measured, not asserted

How well it actually works

An evaluation harness runs three strategies over 150 invoices and 45 simulated days: no chasing, a naive chaser, and Vasooli.

 NaiveVasooli
Recovered, by value85.0%65.1%
Contacts per invoice5.171.10
Compliance breaches920

The naive chaser recovers more. It does so by contacting every customer five times and never stopping — including customers who already paid and customers disputing the bill. Vasooli recovers 77% of that with a fifth of the contacts and no breaches of its own rules. The claim is not “recovers the most”; it is “recovers most of it without behaviour you would be embarrassed to defend.”

Scope

What this is not

A single-merchant system running on test-mode payment keys. It is not multi-tenant, has no billing, and has never processed a real customer's money. What production would require is written up honestly in the repository rather than implied here.