Inspiration

A resident freelancer gets paid 5,000 USDC. Indian tax law tells her exactly which day to value it on — and then, four lines later, never says how to turn that day into a rupee figure. Two honest people reading the same rules file two different, both-defensible numbers.

Every tool I checked hides this. Koinly assumes $0.00 for a missing price; CoinLedger drops the row; CoinTracker uses the midnight-UTC open; Kryptos auto-classifies. Four products, four silent, different resolutions of the same unanswered question. I wanted a tool that refuses to guess — that shows the gap instead of burying it, and hands the human a defence file before any dispute exists.

How I built it

A ten-stage pipeline: five LLM calls and five deterministic Python gates that It contains no model and cannot invent anything.

  • Qwen2.5-7B extracts the facts and detects missing evidence.
  • Qwen2.5-72B resolves each tax regime (income tax, GST) against a scoped, verbatim corpus of law.
  • A valuation lattice (plain arithmetic, no model) enumerates every defensible rupee figure — for the demo case, twelve of them, spanning ₹4,69,750 to ₹5,17,618.76.
  • A citation matcher string-checks every citation against a frozen, SHA-256-hashed corpus, with a tax-year currency check, and drops any Conclusion whose citation fails.
  • A scope-reach enforcer catches a real, current, correctly-quoted provision applied outside its own scope.
  • Mistral-Large — a deliberately different model family — attacks every conclusion and publishes the attack, whether or not it lands.
  • A deterministic composer renders one self-contained HTML workpaper, ending in a human election: the person who signs picks the number.

Models run on Featherless (open weights, no fallback). Everything reproduces with zero API key via a replay cache, and ten checks run in CI on every push.

What I learned

  • The failure that matters isn't a fabricated citation — it's a real, current, correctly-quoted provision applied where its own scope doesn't reach. Standard citation verifiers can't see that; I had to build a separate check for it.
  • Mechanical citation verification is not novel ClearBrieff ships it), and Quantifying a disputed tax position is not novel (Thomson Reuters ONESOURCE). What's new is refusing to collapse to one number — in Indian virtual-asset valuation, with the adversarial attack published either way.
  • Honesty at small n. With six cases, no test reaches p<0.05 unless every case agrees — so I report exact Clopper-Pearson intervals (Jeffreys alongside), never a bare percentage, and say so plainly.

Challenges

  • Building checks that catch my own mistakes: the citation matcher caught five of the project's own historical errors automatically, and the The adversarial checker missed one of four planted defects, which I report at full weight rather than hiding.
  • There is no machine-readable feed of Indian statute text, and the provider's Randomseed is documented as unreliable across servers — so reproducibility comes from a hashed frozen corpus and a replay cache, not from scraping or seeding.
  • The demo record still contains one unsupported claim (an s.393(1) TDS exemption) that its own adversarial checker attacked and landed on. I chose to disclose it rather than quietly fix it — because disclosing what you can't defend is the entire point of the project. ## What it does

Built With

Share this project:

Updates