Notes that point at the exact records they rely on
A note in a saved investigation can now cite up to 16 exact records across both saved results, and a correction keeps every one of them. A link is your reasoning. It is not proof of a connection.
When you write down what you think happened, the sentence is only as good as the records behind it. A note that says "the approval came first, then the funds left" is hard to check a week later if nobody can tell which approval and which transfer you meant.
Forensia already let you add notes to a saved investigation. Until now a note could point at one record only, and starting a correction quietly dropped everything except the first link. Both are fixed. A note can cite up to 16 exact records, they can come from either saved result in the investigation, and a correction carries all of them forward while the original entry stays in place.
One thing does not change. Linking two records says that you relied on them together. It does not say the blockchain connects them.
#Plain languageA note with footnotes, not a note with a hunch
Think of a lab notebook written in ink. You may not erase a line. If you were wrong, you write a new line underneath that says so, and the old one stays readable. Each line carries footnotes that point at specific pages of data, so a reader can go and look.
Notes in a saved investigation work the same way. Every note is one of three kinds: a Note, a Possible explanation, or Conflicting evidence. Each can carry a list of supporting records. A supporting record is one specific item in one specific saved result: a finding, a row of activity, or a source record (the stored description of one response from a data provider).
A saved investigation can hold two saved results, called captures. They might be the same transaction looked up on two days, or two different transactions you want to read side by side. A single note can now cite records from both.
#How it worksAdding, opening and correcting links in the Saved panel
- Run a lookup and choose Save result in the left rail. Open Saved, find the investigation and choose Details.
- Open the Notes section. Pick the capture the note is about under About capture, and choose an Entry type.
- Write the note in Your review entry. It can be up to 2,000 characters.
- Under Add supporting record (optional), choose a record to attach. The list shows every finding, activity row and source record from both captures, each labeled with its capture number and network. Activity rows are numbered so two rows with the same amount can be told apart.
- Repeat to attach more. Each attached record appears in a list with its own Unlink button, and a counter shows how many of the 16 are used.
- Choose Save review entry.
A saved entry shows one button per link, such as Open link 1, naming the result and the record type. Opening a link takes you to that exact record in that capture. Returning brings you back to the same entry.
The saved timeline also lists your entries beside the transactions they cite. In Details, open the timeline and then Your review links. Each saved entry appears with its type (Note, Possible explanation or Conflicting evidence), the words User-authored, and whether it corrects an earlier entry or has a later correction. Under it, each cited activity record is shown with the network and transaction hash it belongs to, next to a button that opens that exact record in its original capture. A button labeled Open note and corrections, with the entry number, takes you to the entry itself without editing it.
An entry can also carry a role. Under Role of linked activity (optional), choose Setup, Authorization, Execution, Onward movement or Cleanup to say what part the linked activity plays in the sequence you are describing. No role is the default. The role is shown on the entry in Notes, beside it in Your review links as Your role, and in the report, each time marked as yours. A correction can change the role or withdraw it, and the original entry is kept.
To change your mind, choose Add correction on the entry. The form loads the original text and every one of its links. Edit the text, unlink or add records, then choose Save correction. The original is marked as having a later correction and remains visible. The new entry is marked as a correction with the original retained.
#Technical detailHow a link is stored and what makes one invalid
A link is a locator made of three fields. It never stores a label, an address or a hash on its own, because a matching label is not the same thing as the same record.
type RecordLocator = { captureId: string; kind: "finding" | "activity" | "source"; recordId: string };
interface ReviewEntry {
id: string;
kind: "note" | "hypothesis" | "contradiction";
body: string;
createdAt: string;
captureId: string;
support: RecordLocator[];
supersedes?: string;
episodeRole?: "setup" | "authorization" | "execution" | "onward-movement" | "cleanup";
}Identity and duplicates
Two links are the same only when all three fields match. The identity key is the JSON array of capture ID, kind and record ID. The same record ID in the other capture is a different link, and a finding and a source record that happen to share an ID are different links. Attaching a record that is already attached does nothing. Attaching a seventeenth throws an error that tells you to remove one first. The selector also disables itself at 16, or when nothing is left to attach.
Resolution
A locator must resolve to exactly one record inside its capture. The resolver scans the capture’s findings, activities or evidence list for the record ID and returns one of three states: resolved, ambiguous (more than one match) or missing. Only resolved is accepted. Captures are also rejected on save if any of those three lists contains a duplicate ID, so an ambiguous target should not arise from a capture Forensia produced.
Corrections
A correction is a new entry whose supersedes field holds the ID of the entry it corrects. The editor copies the full support array into the draft as new objects, so editing the draft cannot alter the original. On import, a correction is accepted only if it refers to an entry that appears earlier in the file and belongs to the same capture.
Write rules
| Rule | Value in the code |
|---|---|
| Links per entry | 16 |
| Captures per investigation | 2 |
| Entries per investigation, corrections included | 50 |
| Characters per entry | 1 to 2,000 |
| Saved investigations in this browser | 5, within 10 MiB in total |
| Size of one investigation package | 2 MiB |
| Nesting depth accepted on import | 32 |
| Investigation, capture and entry ID format | 1 to 120 characters: letters, digits, colon, underscore, hyphen |
Every write must advance the revision number by exactly one from the revision you loaded. If another tab saved first, the write is refused and your draft is kept. Earlier captures and earlier entries are compared in canonical JSON form against what is stored. Any difference is refused with the instruction to add a capture or a correction instead.
Roles and the v3 format
A role is stored as the optional episodeRole field on the entry. It is checked before anything is written. The entry must cite at least one activity record, every citation must resolve, and every cited activity record must be placed on a recorded transaction by the rules below. If not, saving is refused with a message asking you to add an activity link or choose No role, and your draft is kept. Finding and source links may support the note, but they never satisfy this requirement.
Saving a role is what moves an investigation from forensia.investigation.v2 to forensia.investigation.v3. Ordinary notes and existing investigations stay on v2. This build reads the v1 migration format, v2 and v3. An older release cannot import a v3 file, and a v3 investigation cannot be written back as v2. The form says this before you save a role, and Backup and report repeats it. Captures, capture times, manifest digests and earlier entries are not rewritten, and no database migration runs.
Placing a cited record on the timeline
Your review links is a projection of what is already saved. It reads the entries and their locators, and it never infers that a note belongs to a transaction from the note text, from the capture the note is about, from a source record or from a finding’s own supporting records. An explicit citation of one activity record is required.
- Within one entry, citations are collapsed by capture ID, record kind and record ID, so a record cited twice is shown once.
- A citation is counted as unavailable when its capture ID does not match exactly one capture in the investigation, or when the record does not resolve to exactly one record in that capture. No substitute is selected.
- Only an activity citation can be placed. It is placed when exactly one timeline entry contains that activity row in an observation from that same capture. No match, or more than one, leaves it unplaced.
- Source record and finding citations stay openable and read Not placed on a transaction.
- The count of cited transactions is the number of distinct pairs of network and transaction hash, so the same hash on two networks counts as two.
Import and export
A JSON backup is validated strictly when reopened. Unknown fields on an entry or a locator are rejected. Each capture’s snapshot SHA-256 is recomputed over its canonical JSON, the source manifest digest is rechecked, and each stored request is checked against its recorded byte length and SHA-256. Then every link in every entry is resolved again. One missing or ambiguous target fails the whole import.
The Markdown report prints each entry with its kind, time, capture ID and entry ID. A correction is printed with the ID it corrects and the words original retained. Each link is one line naming the capture, the kind and the record ID. Neither file contains raw response bodies.
The report also carries a section named Your review links with the same mapping. For each entry it gives the number and type, whether it corrects or was corrected, the count of distinct transactions its activity links reference, and one line per link stating either the transaction hash and network or that the record was not placed on a transaction. An entry with a role prints it as a user-assigned role that applies only to that entry’s explicit activity links.
This was exercised locally on a saved investigation holding two real Ethereum captures, 0x22fc4a1bba0e2a711a5852f5c835eea4cb764f989895b1b48ec73d84dab8ed95 and 0x7742b66e9c5d18919daf9a64bea9c28eee7b8481d9877c1fb70ac780eec12a87. The two were grouped only to test the workflow, not because they are known to be related. A note linked one activity row from each, its correction kept both links, and the exported backup passed strict import.
#LimitsWhat a link does not establish
- Notes are your interpretation. They are stored and exported separately from observed findings and are labeled as not verified.
- Your review links shows what you cited and nothing more. Shared addresses, nearby times, source records and findings do not create a link between transactions, and grouping citations under one entry does not prove a connection.
- A role is your label. Forensia does not assign roles, and a role is not an observed classification, an assessment of intent, a causal link between transactions or a finding that an exploit took place. Causal dependency edges and detection of a missing earlier step are not implemented.
- Putting two captures in one investigation, or citing both in one note, is not evidence of association, causation or common ownership.
- This is a step toward working across several transactions. It is not a complete multi-transaction causal investigation.
- The limits did not grow. An investigation still holds two captures, so a note can reach across two saved results and no further.
- A link points into a saved snapshot. It says nothing about the current state of the chain, and nothing is fetched when you open one.
- Hashes in the package show the file is internally consistent. They do not prove who wrote the notes or that a provider’s data was correct.
- Saved investigations live in this browser. Clearing browser data removes them unless you downloaded a backup.
- In testing before release, the browser prompt that guards a draft containing only links could not be confirmed end to end. The guard is in the code. Treat that one interaction as untested.