Skip to content
Docs
foxborne.comRequest a pilot

Verify a report against the originals

Check a Foxborne report with the original files and standard tools. You confirm each file's SHA-256, find every excerpt at its location, test each threshold against the raw values and confirm the marking and, when needed, the audit trail.

TutorialMarkdown
On this page5

Every excerpt in a Foxborne report names its file and the SHA-256 of that file, with a line, row or byte offset inside it. Anyone holding the originals can check each line with standard tools and no access to the deployment. This tutorial checks INC-0142 from the example dataset, from the hashes to the audit trail.

What you will have#

A report you have checked yourself. Each file's hash matches, each excerpt sits where the report says and each finding's threshold holds against the raw values. You will also have confirmed the marking and, if the review calls for it, the audit trail.

What you need#

  • The report or the case file, in HTML or JSON.
  • The original files, from where your program keeps them, such as the fleet log archive. Take them from there rather than from the report's author.
  • A shell on Linux or macOS, or PowerShell on Windows.
  • For the audit trail only, the Auditor or Admin role in the deployment.

Check the report#

  1. List the sources the report names

    The Sources line in the report header gives each file with a short form of its SHA-256: the first 12 and last 4 hex digits. Foxborne took the hash when the file arrived. INC-0142 names four files:

    INC-0142, SourcesExample datasetText
    Flight log          14_13_19.ulg               sha256:f60310be1687…f69f
    Companion journal   uas04-orin-journal.json    sha256:a0741c955f33…cdf4
    Process samples     uas04-orin-samples.jsonl   sha256:c4d46f086f9c…8830
    Ground receive log  rc1-receive.jsonl          sha256:a96027361d50…8905

    3 Evidence repeats the short hash on every line. The full 64-digit hash is in each event's Copy reference and in the run's Source files table, where Copy SHA-256 copies it.

  2. Hash each original

    Compute the SHA-256 of each file you hold.

    In the folder that holds the originalsShell
    sha256sum 14_13_19.ulg uas04-orin-journal.json uas04-orin-samples.jsonl rc1-receive.jsonl

    Each command prints one 64-digit hash per file. For the companion journal, the example dataset records this line:

    Expected output for the journalExample datasetText
    a0741c955f3301a6dffc1a85c93e0eb315e53227c790f517ff7d484e98e0cdf4  uas04-orin-journal.json
  3. Compare the hashes

    Match the first 12 and last 4 digits against the Sources line, and the whole hash against Copy reference when you have it. Foxborne hashes every original on arrival and never rewrites it, so a match shows that you hold the same bytes the report was built from.

    A mismatch means a different file: a later export, an edited copy or a truncated transfer. Stop there, find the original and hash it again.

  4. Find each text excerpt at its location

    For the journal, the samples and the receive log, the location is a line or rows in the file. Print it and compare the excerpt byte for byte.

    EvidenceFileLocationOn Linux or macOS
    E3, the kernel killuas04-orin-journal.jsonLine 18,314sed -n '18314p' uas04-orin-journal.json
    E1, memory above thresholduas04-orin-samples.jsonlRows 2,811 to 2,813sed -n '2811,2813p' uas04-orin-samples.jsonl
    E6, the heartbeat gaprc1-receive.jsonlLines 1,118 and 1,119sed -n '1118,1119p' rc1-receive.jsonl

    In PowerShell, (Get-Content .\uas04-orin-journal.json)[18313] prints line 18,314, because PowerShell counts lines from zero.

    A journalctl JSON export holds one entry per line, so line 18,314 is the whole kill record. Its MESSAGE must match E3's excerpt exactly:

    E3, the excerptExample dataset, INC-0142Text
    Out of memory: Killed process 2213 (perception_node) total-vm:11873248kB, anon-rss:6823516kB, file-rss:10240kB, shmem-rss:0kB, UID:1001 pgtables:14720kB oom_score_adj:0

    The same line carries __REALTIME_TIMESTAMP 1790260324118000, in microseconds since the epoch. That is 14:32:04.118 UTC on 24 Sep 2026, the time the report's sequence gives. Its _BOOT_ID begins 9b2e4c1d, the boot ID the process samples share with the journal.

  5. Find the flight log excerpt

    A flight log is binary, so its excerpt is the decoded message rather than raw text. E2 gives Message 1,146,099, byte 53,503,302 in 14_13_19.ulg: message 1,146,099 of 1,388,540, starting 53,503,302 bytes into the file.

    Decode the message that starts at that offset with your ULog tools, then compare its topic, timestamp and fields with the record. The report quotes the topic and the first three fields, and the evidence inspector shows the whole record:

    E2, the record in the evidence inspectorExample dataset, INC-0142Text
    topic      obstacle_distance (multi_id 0)
    timestamp  1,132,793,000 µs   boot + 1132.793 s
    message    1,146,099 of 1,388,540
    offset     byte 53,503,302
    
    frame                       12 (MAV_FRAME_BODY_FRD)
    sensor_type                 0 (laser)
    min_distance                20 cm
    max_distance                2000 cm
    increment                   5.0 deg
    distances[0..7]             412 406 399 401 388 1999 1999 1999

    The timestamp counts microseconds from boot. PX4 ULog explains how Foxborne anchors it to UTC.

  6. Check each rule and its threshold

    Each finding names the rule, the version and the threshold that produced it. The console shows them in the evidence inspector's Rule block and on the event page. There, E1's Rule reads memory_pressure 1.1: RSS at or above 6,144 MiB for 3 samples.

    Test the threshold against the rows you printed. Rows 2,811 to 2,813 carry rss_kib values of 6,336,512, 6,555,648 and 6,814,720. Divided by 1,024, those are 6,188, 6,402 and 6,655 MiB: three samples in a row at or above 6,144 MiB, as the rule requires.

    E6 checks the same way. telemetry_gap 1.3 fires on "More than 3 s without a HEARTBEAT". The two receive lines read recv_utc 14:32:03.912 and 14:32:10.874, 6.962 s apart.

    A finding keeps the version and threshold that made it. If the Rules page now shows a later version, the report still stands on the one it names. See Thresholds, scopes and overrides.

  7. Confirm the marking

    The marking sits at the top and bottom of every page, with the designation indicator on the first page.

    CUI
    Controlled by
    Your organization
    Controlled by
    Your office
    CUI category
    EXPT
    Dissemination
    FEDCON
    The marking banner and designation indicator of a CUI report. The organization, office and contact shown here are examples.

    Compare the category, the dissemination control and the point of contact with your program's marking guide. The marking comes from Settings in the deployment. If it is wrong, an admin corrects it and the report is exported again.

  8. Verify the audit trail, if the review needs it

    Someone with the Auditor or Admin role opens Audit log in the deployment.

    1. Type the incident ID into Filter by person, action or object, or pick Evidence or Reports.
    2. Read the entries, such as Viewed evidence, Edited report, Aligned clock by hand and Exported case file, each with its person, time and detail.
    3. Select Verify chain. The console reads "Recomputing each hash from the entry and the hash before it." and ends with Chain intact. Every entry matches.
    4. To check the chain offline, select Export and choose JSON Lines or CSV. "The export includes each entry’s hash and the hash before it, so it can be verified offline."

    Each entry's Entry cell shows its number and the first 8 digits of its hash. Its tooltip holds the full hash and the hash before it. See Audit log.

What you have now#

  • Each file's SHA-256 matches the report, so you hold the originals it was built from.
  • Each text excerpt matches its line or rows byte for byte, and the flight log excerpt matches its decoded message.
  • Each finding's threshold holds against the raw values.
  • The marking fits your program's guide.
  • If the review needed it, the audit chain is intact.

Next#