-
-
The plan: the most Maya can safely pay today, found across 2,000 simulated futures of her income
-
What happened? Claude reads "I lost my delivery gig for 3 weeks" in plain words and re-plans
-
Payment cut from $1,075 to $325, and Claude asks first: keeping $1,075 would mean a 56% chance of a missed payment
-
Credit feed down (simulated): safe mode uses the last good data and never raises payments
-
Six-month test on 200 simulated futures: DebtPilot had the lowest expected cost of 5 strategies
Inspiration
Every debt app gives the same advice: pay your minimums, then send every extra dollar to the highest-interest card. That advice assumes a steady paycheck. For freelancers, gig workers and hourly staff, income can be $1,180 one week and $0 the next.
For them, the real question isn't which card to pay. It's how much they can afford to pay at all without being short on rent or a minimum payment next week. Pay too little and interest piles up; pay too much and one slow week brings late fees and a penalty APR. I built DebtPilot to model exactly that trade-off.
What it does
DebtPilot loads a person's debts and cash history, then keeps their payment plan up to date as life happens.
- A safe payment, not just a target. From the last 10 weeks of income it simulates 2,000 possible next eight weeks. For every extra payment from $0 up to all available cash, it measures the chance of missing rent or a minimum and the expected cost: interest plus late fees plus penalty APR. It recommends the cheapest payment that keeps that chance under 5%. For my demo persona, Maya, that's $1,075. Paying all $1,820 would save $23 of interest but cost $62 more overall, because she'd miss a payment in almost half the futures.
- "What happened?" in plain words. Type "I lost my delivery gig for 3 weeks" or "Card B raised my APR to 29.99%". Claude turns it into a structured event, the planner re-runs, and the agent explains the change. Maya's safe payment drops from $1,075 to $325.
- Asks before acting. Any change to the plan becomes an approval request written by the agent. Nothing is paid without a yes.
- Recovers when data fails. If the credit bureau feed goes down, the agent retries once, carries on with the last good snapshot, and switches to safe mode: payments can go down but never up until the data is fresh.
- Shows its work. Every tool call, number and decision lands in a live audit log, and an Ask DebtPilot box answers questions using the same tools.
- Proves it over six months. A built-in comparison runs DebtPilot against the usual advice ("keep a cash buffer, send the rest to the highest-APR card") through the same 200 simulated half-years. After a lost gig, DebtPilot had the lowest expected cost ($542), while the best fixed rule's chance of a missed payment rose from 10% to 32%. In normal times that rule misses payments less often than DebtPilot (10% vs 16%) but costs more.
How I built it
The core design: Claude decides what to do; code does the math and enforces the rules.
- Planner engine (TypeScript). Income futures come from a block bootstrap of the income history, resampled in two-week runs so dry spells stay together. A week-by-week simulator pays cash-only bills (rent) first, then debt minimums plus anything past due, then spending that can go on a card with room left. A missed card minimum adds a late fee and a penalty APR. Every candidate payment is scored on the same simulated futures. A full search (about 70 payment amounts × 2,000 futures) takes under a second.
- Claude agent (Claude Opus 5.5, Anthropic TypeScript SDK). A tool loop with five tools: get_financial_state, simulate_plan, compare_plan, refresh_credit_data and request_approval. Every call is written to the audit log. Free-text events are parsed with structured outputs, then validated and clamped in code. If Claude is unreachable, a rules-based agent runs the same tools.
- Guardrails in code. Approval whenever the plan changes, safe mode while credit data is stale, a forced re-sync after an outage, and accounts in collections kept out of the plan.
- Convex backend. Profiles, plans, approvals, questions and the audit log live in Convex. Every event schedules an agent run, heavy simulation runs in background actions, and a live query keeps the Next.js dashboard current without refreshes.
- CRS credit data. Pulls Experian reports for CRS test identities and maps tradelines to debts: balances, limits, minimums, past-due amounts and payment status. Collections are detected and set aside for a counselor.
- Capital One Nessie. Creates a sandbox customer and account, posts weekly income as deposits, and reads balance and deposits back into the weekly history the planner simulates from.
- 31 automated tests cover the planner, the backtest, the event parser and both data adapters.
What's real vs. simulated
- Real: the planner math, the Claude agent (live API calls), the Convex backend, and live calls to the CRS and Nessie sandboxes.
- Real sandbox, synthetic people: CRS reports are for CRS's provided test identities; the Nessie account and deposits are created by DebtPilot.
- Typical values, labeled: CRS doesn't report APR or due dates, so those show as "manual" in the app.
- Synthetic: Maya, the demo persona.
- Simulated: income futures, the 26-week comparison, the credit-feed outage (a labeled demo toggle), and payments (approving a plan records the decision; no money moves).
Challenges I ran into
- A planner that only looked smart. Minimizing interest under a risk cap just picks the largest payment under the cap. Counting the real cost of a miss made it a genuine trade-off.
- Keeping the comparison honest. My first backtest depended on the cash buffer I picked for the usual advice. I tested several buffers and scenarios and report where a fixed rule wins.
- Real credit data broke my assumptions: collection accounts marked "Open", several accounts with the same creditor name, and cards without a reported limit.
- Fragile sandboxes. Repeated failed CRS logins disable the account, so a failed login locks further attempts. Date-only Nessie transaction dates shifted the income history by a week until I fixed the bucketing.
Accomplishments that I'm proud of
- The live re-plan: one sentence in plain words changes the plan, with the reasoning and an approval request seconds later.
- An agent that handles a real failure: it retries, falls back to the last good data, and says exactly what it did.
- Guardrails enforced in code, not just in the prompt, and live data from two sponsor APIs, labeled field by field.
What I learned
- Language models are good at judgment and explanation and shouldn't do the arithmetic. Splitting the two made the agent trustworthy and easy to audit.
- With irregular income, uncertainty is the whole problem. A simulation over many futures says more than any single forecast.
What's next for DebtPilot
- A counselor view across many clients: routine changes handled automatically, risky ones escalated.
- Real bank and payment connections behind the approval step.
- A six-month risk setting and longer income histories.
- Help negotiating accounts in collections.
Built With
- anthropic
- capital-one-nessie
- claude
- convex
- crs-credit-api
- next.js
- node.js
- react
- typescript
- zod
Log in or sign up for Devpost to join the conversation.