Inspiration
None of us knew what a CFDI was when the weekend started. We spent the first hours reading Mexican tax law instead of writing code — and found that the tax authority publishes four statuses for flagged companies, two of which mean the vendor was cleared.
Then the scoring rules told us the rest: a system that accuses every vendor reaches perfect recall and scores badly. So we optimized for the opposite problem — being able to defend every accusation we print.
What it does
You hand it a company's books. It returns a case file: the scheme, the peso amount, a money trail as a diagram, every document cited by its real id — plus the leads it investigated and chose not to accuse.
Three roles, each blind to what the others decided:
Investigator — builds the case using eight SQL tools Challenger — a second model that builds the strongest innocent explanation it can Validator — code, no model: every citation must exist, every peso must reconcile within 2%
Nothing prints without surviving all three.
How we built it
Python, SQLite, a local model via Ollama, React. The challenge ships no dataset, so we also built the generator that produces a full synthetic company from a seed.
Challenges we ran into
The 7B model kept inverting its own conclusion — reasoning correctly, labeling backwards. We made it return an unambiguous word and translated it in code.
Our "clean" data contained accidental fraud. A vendor landed on the tax blacklist by chance with no contract, structurally identical to a real scheme. Not an agent bug — a generator bug that made our metrics meaningless. 35 of 40 seeds were affected.
We had a constant where we needed an inference. The approval threshold was hardcoded; the judges generate their own. Now we infer it, and if the inference isn't conclusive the detector doesn't run. Inventing a threshold produces false accusations.
Accomplishments that we're proud of
We built the baseline that could have made us look bad. One SQL query: flag anyone on the blacklist with no contract. Across ten held-out seeds it accuses 33 vendors — 6 real, 27 innocent. 82% of everything it says is wrong. We accuse 19, none innocent.
The Challenger catches our own mistakes. Our best case is a lead that passed the Investigator and was about to become an accusation — the Challenger found a documented payment that explained the whole flow and killed it.
Zero pesos on a laptop. Under ten model calls, ~50s per estate, running locally. Client books never leave the network.
What we learned
Read the law before writing the code — almost every good decision came from the statute, not from us.
A perfect score is a warning sign. We got 100% recall on held-out seeds, but those estates come from our own generator. Saying that before anyone asks is worth more than the number.
The model should never do arithmetic. One invented figure in front of finance consultants ends your credibility.
What's next
Entangled schemes. A wider vocabulary of innocent explanations — the Challenger knows four, real business has more. Connectors to real ERPs: the inputs map to what Mexican companies already keep by law, so what's missing is plumbing, not reasoning.
Log in or sign up for Devpost to join the conversation.