Divergence

It doesn't tell you the tax number. It proves which numbers you can defend.


The disagreement

One receipt. Two lawful answers. A gap nobody discloses.

A resident freelancer in India is paid 5,000 USDC by a foreign client, settled on a weekend when no official rate was published. Indian tax law says which date to value it on. It does not say how to turn that date into a rupee figure.

SBI TTBR 2026-06-29 — next published after the receipt ₹4,69,750.00 SBI Forex Card Rates sheet, USD/INR TT BUY
Domestic market high × retrieved peg ₹5,17,618.76 CoinDCX I-USDT_INR daily candle (high)
₹47,868.76 · 10.19%

Two accountants, the same law, the same evidence, ₹47,868.76 apart. Every commercial tool prints one of these and hides the other.

Source: runs/21aug/D1_final_seed2.jsonvaluation.methods[], valuation.spread, valuation.uncertainty_budget[]. A real frozen record, not an illustration. Twelve methods are defensible; the lowest and highest are shown.


Three real records

Twelve answers. One answer. One answer.

The same pipeline, the same unchanged code, run against three different real receipts. The point is not that it always finds a dispute. It is that it finds one only when the law leaves one — and says so plainly when it doesn't.

D1 — the hard case

Stablecoin, weekend settlement

USDC received on a Sunday with no published bank rate. Twelve defensible valuation methods, none of them chosen for you.

12methods
Open the record →
C1 — the control

Plain domestic invoice

INR to INR, no conversion at all. One method, zero disputes. The system does not manufacture uncertainty to look clever.

1method
Open the record →
C2 — the scalability proof

An ordinary cross-border wire

No crypto anywhere. The same machinery works on a bank transfer — the method is not a stablecoin trick.

1method
Open the record →

Every page above is rendered by node7_disclosure.py from the frozen record. No hand-editing after generation.


How it works

Ten steps. Five can be wrong. Five cannot invent.

A model can hallucinate a citation. Plain code cannot. So every claim a model makes is passed through gates that hold no model at all — string matching against a frozen, hash-pinned corpus, a date check, and arithmetic.

  • 5 × model callExtract, gap detection, income-tax resolver, GST resolver, and an adversarial checker deliberately run on a different model family so it is not grading its own homework.
  • 5 × deterministic gateCitation matcher, scope-reach enforcer, gap-constraint enforcer, valuation lattice, disclosure composer. If a citation fails, the whole conclusion resting on it is dropped, not flagged.

Open models throughout, via Featherless: Qwen2.5-7B-Instruct, Qwen2.5-72B-Instruct, and Mistral-Large-Instruct-2411 for the adversarial pass. No Claude in the loop, on purpose — a silent provider switch would put a Claude-generated row in a table labelled "open models".

DIVERGENCE pipeline flowchart: ten steps, five LLM calls and five deterministic gates, from human input through to an optional human election.
The full pipeline — click to enlarge

Verify it yourself

Reproduce the entire demo run with zero API calls.

You do not need a key, an account, or our goodwill. The demo record is replayed from a recorded run that is checked in and gated in CI. If the numbers on this page were invented, this command would not produce them.

Reproduce D1
git clone https://github.com/hariom-s27/divergence
cd divergence
pip install -r requirements.txt

DIVERGENCE_REPLAY=1 python -m divergence.run_pipeline \
    --record-id D1-verify \
    --tax-year "FY 2026-27" \
    --text divergence/cases/D1/input.md \
    --node5

Replays 5 model calls, 29,559 input / 3,042 output tokens, and writes a record whose facts, gaps and attacks are byte-identical to the frozen one.


Where we lose

Our own checker attacked our own shipped output. It landed. We kept it.

Attack landed

"No deduction obligation arises under s.393(1) as the recipient is a resident and the payer is outside India."

Section 393(1) does not exempt payments from non-residents to residents from the deduction obligation. The conclusion is not supported by the text it rests on.

This is not a hypothetical. That claim is still in the frozen, shipped demo record. It was attacked live by a different model family, the attack landed, and it was left in place rather than quietly patched before submission. The project's own results.md says so under "Where we lose", and said so before this page did.

Source: runs/21aug/D1_final_seed2.json (regimes[0].outcome) and D1_final_seed2_attack.json (attacked[1]) — quoted verbatim.


Everything else

Read further