Docs / Operate
Where a claim came from
ivralo why answers the question a reader of a result asks: where did this number, or this sentence, come from. It follows the claim back through what ivralo recorded to the file, the line or the tool output it rests on.
Asking
Give it a run and a claim. The run is named as ivralo trace names one: last, or the first eight characters or more of its id. The claim is a number or a phrase from the answer.
ivralo why last "18%"
"18%" - traced to its sources
"18%" in the reply of run 5bbbbbbb · step 5 «Write the report»
← step 4 «Compute growth», which step 5 needs (declared) · run 4aaaaaaa
← "18.0" in the reply of run 4aaaaaaa · step 4 «Compute growth»
← "18.0" in the output of run_python (read_excel('sales.xlsx')) · Data Analyst · step 4 «Compute growth»
← sales.xlsx · version 20261002-101500-123456 in history - the one read
Read it from the top: the claim where it was written, then each recorded fact it came from, down to the source. A sentence works too; each number in it is traced on its own.
In the session, /why <claim> traces the last answer and prints the same lines. It only reads, so it works while a turn is still running.
A join, never a model
The chain is computed from what ivralo already stored. No model is asked, because the model that wrote the number is the one that would invent its source. The join reads:
- the run's reply and the files it wrote;
- every tool call's arguments and output;
- the version history kept before each overwrite;
- the chunks a knowledge search returned, with their section, slide or page;
- the steps a plan step declared it
needs, which is how a chain crosses from step 5 to step 4; - an instance's own run, when the claim came from a side instance's report.
A number matches by value however it is written: 18%, 18,0 and 18.0 are one number, and 1,842 is read both ways. There is no rounding and no arithmetic. A reply that says 18% over an output of 17.96 is not traced to it.
The version is the one that was read. History keeps a copy before every overwrite, so the first copy kept after a read is what the read saw. With none kept after it, the chain says "the working copy, no later version kept". It never claims a file was unmodified: history cannot prove that.
Where the record stops
The chain stops where the record stops, and says so in plain words rather than guessing:
| The chain ends with | Meaning |
|---|---|
computed in step 4 by run_python, inputs not recorded | Code produced the number but named no file ivralo could follow |
written by the model; no recorded output holds "18%" | Only the reply holds it. No tool ever returned that value. |
cannot be traced | The claim was found nowhere in the run |
step 3's run is not recorded | A step the chain needs has no stored run |
Incident reports reach their evidence
An incident report is traced past the tools to the bundle itself. Every fact in the digest the Investigator read names the evidence line it came from, and each filed hypothesis names the lines it cites, so the chain ends at a file and a line:
ivralo why -s <session> last "the claim, as it appears in the report"
incident/deploy.log · line 3 - the evidence line read_incident's digest cites
The line is checked against the incident's digest.json under .ivralo/incidents/, so only a line the bundle held at the time is cited. With that file gone, the chain ends at the tool.
Reports carry their sources
When a plan step creates a Markdown or Word file, ivralo ends it with a Sources section written from the same record: the files the step read with the version read, the chunks with their places, what an outside tool returned, and the steps it needs. It lists sources only, never a claim, and says "Sources not recorded" when the step read nothing ivralo recorded. A later step that rewrites the file replaces the section. Code, PDFs, decks and workbooks get no section; ivralo why is their answer.
In scripts
| Option | Does |
|---|---|
--json | The chain as one JSON object on stdout |
--session, -s | Read a run from another conversation |
The exit code answers the question a script asks:
| Exit | Meaning |
|---|---|
0 | Every branch reaches a file, a chunk or a tool's output |
1 | It does not, or the claim cannot be traced |
2 | The run could not be read |
The chain goes to stdout and an error to stderr, so a pipeline sees only the result.