When two captures disagree, Forensia keeps both versions
Saved captures are compared occurrence by occurrence. Differing amounts, recipients or status are shown side by side with both values. Forensia does not decide which one is correct.
If you look up the same transaction twice, you expect the same answer. Usually you get it. Sometimes you do not: a source returns a different amount, a different recipient, or reports a failure where an earlier capture reported success.
Most tools resolve this quietly. The newer answer replaces the older one, and the fact that two records disagreed is gone. For an investigator that is the wrong outcome, because the disagreement is itself something to explain.
Forensia compares two saved captures record by record and keeps every difference it finds. Both values stay visible, each tied to the capture it came from and the time that capture was taken. It does not choose a winner, and it only compares records it can match exactly.
#Plain languageTwo copies of a ledger page
Suppose you hold two photocopies of the same ledger page, made on different days, and line 14 shows a different figure in each. A careful auditor does not cross one out. They note that line 14 differs, write down both figures, and record which copy each came from.
They also only compare line 14 with line 14. A line that appears in one copy and not the other is not a contradiction; it is just missing from one copy. A smudged figure is not a contradiction either. It is unknown.
Those three rules are the whole design: match the exact same item, treat missing and unknown as missing and unknown, and keep both versions when two known values differ.
#How it worksRunning the comparison on a saved investigation
- Save a result with Save result, run a second lookup, then open Saved, choose Details, and choose "Add current result". The comparison needs two results in one investigation.
- In Details, open "Timeline across saved results", then open "Compare recorded activity". If anything differs, the heading already shows the number of differing occurrences.
- Read the first line. It states how many exact occurrences were compared and whether any recorded fields differ.
- Read the second count: how many records were unpaired and how many were unsupported or ambiguous. These were not compared.
- For each difference, read the field name (for example To, Execution status or Raw quantity) with the Result 1 and Result 2 values beside it, and the capture time of each result.
- Choose "Read result 1 activity" or "Read result 2 activity" to open that exact row inside its original capture.
The same comparison is written into the Markdown report prepared from the saved investigation, with both values, both capture times and the record identifiers.
#Technical detailHow records are matched and which fields are compared
Occurrence identity
Two rows are compared only if they are the same occurrence on the same resolved network. An occurrence is a canonical identifier, never a guess based on similar addresses, amounts or token symbols.
| Record | Identifier | Shown as |
|---|---|---|
| EVM outer transaction (native transfer, contract call or deployment) | native:<transaction hash> | Outer transaction |
| EVM token event | token:<transaction hash>:<receipt log index>, plus a batch item index when one was retained | Token log N, and batch item for multi-token events |
| Bitcoin input or output | utxo-input or utxo-output:<transaction id>:<position> | Bitcoin input N or Bitcoin output N |
The receipt log index is what makes a token event portable: it is the position of the event log inside the transaction receipt, so it means the same thing in any capture. Two kinds of row have no such identity and are excluded: internal calls, whose ordinal depends on how a trace was read, and wallet-level Bitcoin totals, which are aggregates and not a specific input or output.
What excludes a row
- The capture’s network cannot be resolved to one known network by chain key, chain ID, family and network ID.
- The row has no portable occurrence identity.
- Any source record the row cites is missing from the capture, appears more than once, or does not have captured status. A row with no source reference at all is also excluded.
- The row is already flagged inside its own capture as having conflicting source records.
- The row ID or the occurrence appears more than once in the same capture.
Excluded rows are counted and reported. A row that qualifies but exists in only one capture is counted as unpaired. Unpaired is not a disagreement.
Fields
A field is reported as different only when both captures hold a known value and the values are not equal. If either side is unknown, the field is skipped.
| Field | Compared as | Notes |
|---|---|---|
| From, To | Address, lowercased on EVM | An EVM value that is not a 20-byte address counts as unknown |
| Execution status | success or failed | Any other status is unknown |
| Asset contract | Token contract address, or "Native asset" | Never the token symbol |
| Token encoding | native, erc-20, erc-721 or erc-1155 | |
| Raw quantity | Exact integer string | Only when contract and encoding are identical on both sides |
| Token IDs and raw quantities | List of ID and quantity pairs | ERC-721 and ERC-1155 only, same condition |
| Recorded decimals | Integer from 0 to 255 | Skipped when the row carries a decimals conflict |
Quantities stay as exact integers in base units. Nothing is rounded, summed or subtracted, so the comparison never produces a net amount. Display labels, rounded display values and the in or out direction relative to the looked-up address are not compared, because they depend on the lookup and are not facts from the source.
Limits in the code
The comparison handles at most two captures and at most 1,024 activity rows across both. Above either number it declines entirely and says so. It does not compare the first 1,024 rows and stay silent about the rest.
Disagreements the timeline itself preserves
Field differences are one layer. The timeline that contains this comparison also keeps disagreements about placement, without choosing a side:
- Different block numbers for one transaction, or different block hashes for one height, show as "Conflicting block positions" and the entry is left unplaced.
- Different reported times for one block withdraw the combined time and show "Reported times conflict or are invalid".
- Outer records that report both success and failure give the observation the heading "Conflicting transaction records". "Failed transaction attempt" requires every outer record to report failure.
What stays untouched
The comparison is derived when you open it. It reads the saved interpretations in each capture, not the raw response bytes. The captures, their SHA-256 snapshot digests, their capture times and their source records are not modified, merged or re-timestamped.
The in-session counterpart
A lighter notice exists for unsaved work. When you capture the same subject on the same network more than once in a session, Overview can show that your captures do not match. It compares only the sets of transaction hashes each capture retrieved, against up to three other captures, and reports how many transactions each side has that the other lacks. It offers the other capture to open and keeps their evidence separate. It does not compare amounts or recipients.
#LimitsWhat a reported difference does and does not mean
- A difference does not identify which capture is correct. Neither is preferred.
- No differences does not verify either capture. Both may repeat the same provider’s answer, so agreement is not independent corroboration.
- The comparison reads saved interpretations. It does not re-check raw source bytes and does not re-execute anything on chain.
- A difference in quantity is not a balance change, and nothing here attributes funds to anyone.
- It is not a complete audit across captures. Internal calls, aggregates, unsourced rows and unresolved networks are left out by design.
- It says nothing about why two records differ. A provider error, a different chain view and a changed interpretation all look the same here.
One more thing should be stated plainly. The reviewed real example, two captures of Ethereum transaction 0x22fc4a1bba0e2a711a5852f5c835eea4cb764f989895b1b48ec73d84dab8ed95 taken on consecutive days, compared 31 exact occurrences, found no differing fields and excluded two internal-call records. The difference handling has been exercised with constructed test records, not with a contradiction observed from a live provider.