Check
Check a record from your own code with records.check, or with nothing but the history file and the standalone checker.
There are three places a record gets checked, and they run the same check. The Shared Record runs it in the reader's browser when the record opens. records.check runs it in your own process. The standalone checker, @pacspace-io/check, runs it for anyone who holds the history file, with no account, no key, and no PacSpace.
What the check does: for every committed entry, recompute the seal from the sealed record in the receipt and compare it with what was committed; confirm the entries are the ones the record says it has, in order; and confirm the file's own fingerprint. With expect, it also says whether the fingerprints you hold are among the committed ones. A passing check means the record is unchanged since it was committed. It does not show that what was recorded was true.
From code
const history = await pac.records.history({ record: 'build-2026-09-15-0417' });
const result = await pac.records.check({
history,
expect: [{ entry: 1, payloads: [ref] }], // entries count from 1
});
result.ok; // true when every check passed
result.entries[0].expected; // true when your fingerprint is among the committed ones for entry 1
result.failedCheck; // null, or the name of the first check that failed
result.reason; // a sentence, when a check failed
result.sourceChecked; // true only when `source` was given and readexpect[].entry and each result's entry count from 1, as every page does; the history file itself keeps the wire's seq, counted from 0, because the check compares the file by its own fingerprint. The TypeScript check runs the whole check in your process: every seal, the order, and the file's fingerprint. Pass source and it also reads what was committed from outside PacSpace, and sourceChecked says so. check never throws on a failed check; the result names it.
The Python check today compares your fingerprints with the committed payloads and reads each entry's status. It does not recompute the seals. For the whole check from Python, hand the history file to the standalone checker below.
Without PacSpace
Save the history file and run the checker. It reads the public source for the record and never calls PacSpace.
npx @pacspace-io/check history.jsonWith the fingerprint printed on a statement, so the checker also says whether that statement was printed over this exact file:
npx @pacspace-io/check history.json --fingerprint 0x7079b0ac...It prints a few labeled facts and then plain sentences: how many entries the record has, that they are all here, and how many match what was committed, whether the record agrees with the public source, whether the daily statement matches, and whether the fingerprint you gave names this file. The last sentence is always the same, because it is the boundary of the check: the check shows the record is unchanged since it was committed; it does not show that what was recorded was true.
--offline checks the file alone. --json prints the report as a document your code can read. Exit code 0 is a pass; 1 is a check that did not pass; 2 is a file or arguments that could not be used; 3 is a public source that could not be reached, with the file's own check still printed. Node.js 18 or later.
What a failure looks like
A failed check names the first thing that failed, in the order the check runs. The Shared Record says it in a sentence: "This record has 3 entries. 2 match what was committed. Entry 2 does not match." records.check names the check in failedCheck and gives a reason; the checker prints the entries that did not match and the ones the file does not carry. A history that cannot be read at all is refused before any entry is checked.
Which check to use
| You hold | Use |
|---|---|
| A key and the record id | records.history then records.check, in code. |
| A history file and no key | npx @pacspace-io/check history.json. |
| A link and a code | Open it. The check runs before you read a word. |
| A printed statement and the file | The checker with --fingerprint. |