why-agent — an agent that answers why, and cites every sentence
Nebius × NVIDIA Global AI Hackathon · Best Apps and Agents track · runs on Nebius Token Factory with NVIDIA Nemotron 3
Try it — the reconciler, running in this tab
Pick a case, untick a source, or type a different value into a claim.
The verdict on the right is recomputed from what is on screen: this is the reconciler
the Python runs, not a video of it. No key, no server, no network — the corpus and the
reconciler are both in this page. The JavaScript is a port of
evidence.reconcile(), and test_demo_app.py runs both over every
item in every corpus and fails if a verdict, a conflict, a gap or an aspect differs.
| Source | Aspect | Value | What it claims | Locator |
|---|
—
What it does
Give it a work item. It reads what the card says, what the receipt says, what the commit says, what the check run said, and what two Nemotron reviewer models said — and then it tells you what happened, with the citation attached to each line. When the sources disagree it does not pick a winner: it shows every side, cites every side, and says which source is authoritative for what.
The answer it gives
This is the tool's real output, not a mock-up — the excerpt is taken
verbatim from python3 demo.py when this page is generated, so it cannot
drift into a nicer story than the tool tells.
CASE why-alpha — the sources disagree ------------------------------------------------------------------------------ # Why: Ship the alpha release notes **Item:** `why-alpha` **Verdict:** CONFLICTED **Sources read:** 4 The sources disagree. That is the finding. ## What the sources say ### outcome - **receipt** — the burn-down receipt says nothing was claimed → `not-claimed` · `synthetic/notes/alpha.md — synthetic/notes/alpha.md:4` ### state - **card** — the card was marked DONE → `DONE` · `synthetic/cards/alpha.md — synthetic/cards/alpha.md:9` - **commit** — a commit merged the fix → `merged` · `git — 0c4f1a9 (synthetic)` - **check** — the gate run is still red → `failing` · `ci — synthetic://run/alpha/42` ## Conflicts ### state - `DONE` — the card was marked DONE · `synthetic/cards/alpha.md — synthetic/cards/alpha.md:9` - `merged` — a commit merged the fix · `git — 0c4f1a9 (synthetic)` - `failing` — the gate run is still red · `ci — synthetic://run/alpha/42` **A single answer here would be a guess.** Each side is cited; the reader decides which source is authoritative for that aspect. ## Unknowns - **cause** — no source says anything about this. These are UNKNOWN, not passes. An aspect nobody reported is a gap in the evidence, and it is recorded as one. ## What to check next - Resolve the state conflict between `synthetic/cards/alpha.md — synthetic/cards/alpha.md:9`, `git — 0c4f1a9 (synthetic)`, `ci — synthetic://run/alpha/42` — one of them is out of date, and which one is a decision, not a lookup. - Find a source for cause: nobody reported it, so it is UNKNOWN rather than fine. > A card says DONE, a commit says merged, a check says red, a receipt says nothing was claimed. Four sources, four answers. The agent does not pick one — it shows all four and says which one is authoritative for what. ------------------------------------------------------------------------------
What the run measured
An adversarial corpus of 14 planted-claim work items, with a truth file the lanes never see. The deterministic reconciler is the only thing that decides; the model lanes contribute claims and an advisory verdict.
| Scorer | Correct | False approvals | |
|---|---|---|---|
| The deterministic reconciler (the gate that ships) | 14/14 | 0 | |
| Reviewer — deep (the contested items) | nvidia/Nemotron-3-Ultra-550b-a55b | 9/14 | 1 |
| Reviewer — fast (the everyday call) | nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B | 6/14 | 2 |
The lanes err in both directions — the fast lane believed a card that
claimed a failed deploy had shipped. That gap is the architecture, not a bug: the
lanes advise, the reconciler decides. Reviewer-lane cost $0.033,
0 retries. Reproduce it:
python3 benchmark/score.py --eval-results benchmark/eval-benchmark-2026-10-28.json
The lanes, and what each one is for
| Lane | What runs it |
|---|---|
| Narration | nvidia/nemotron-3-super-120b-a12b |
| Reviewer — fast (the everyday call) | nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B |
| Reviewer — deep (the contested items) | nvidia/Nemotron-3-Ultra-550b-a55b |
| Vision — receipt images into claims | nvidia/Nemotron-3.5-Super-VL |
| Live evidence — the web, queried at run time | Tavily search API, via tavily_lane.py |
The live-web lane queries Tavily at run time, and a page becomes evidence only if the claimed value literally appears in it — 3 rows across 3 of the corpus items are Tavily's, and one of them records a miss rather than dropping the row. A page that does not match cannot quietly become a pass.
Every lane output enters as a claim, never as a verdict, because any integration can be poisoned. The model may write the prose; it may not add a fact — every value a narration states is checked against the evidence, and a value that is not there is reported, not removed.
Run it yourself
git clone https://github.com/Snedz/why-agent && cd why-agent
python3 demo.py # the cases, as a reader sees them
python3 benchmark/score.py --eval-results benchmark/eval-benchmark-2026-10-28.json
python3 demo_lab/flip_check.py # proves the model lanes change the verdict
Earlier build
Synthetic data only — no real card, customer or identifier. The reconciliation is deterministic Python; the model writes the prose and is checked against the evidence. The model runs were real: 14 items, 51 claim rows, recorded 2026-10-28.