FACTUM

Demonstration

Proof you can run twice.

One document, certified twice. Every answer, every absence, every computed value and every derivation came back the same. Then one digit of the certificate is changed, and it no longer verifies.

Recorded outputTwo certify calls, made 2026-11-05 against the engine at its current release, on one document of Factum's frozen corpus. This page is built from the two response bodies. It is not a live run and nothing on it is a mock-up.

The corpus document is a synthetic invoice with a fictitious carrier. The run used no AI engine key, so the five prose sections were refused by name instead of written. The two certificates are signed by a development key minted for this recording, published below. It is not the production issuer key. Live runs on the frozen corpus are provisioned with a demonstration ID: request access.

Run it twice

POST /api/tenants/{tenant}/certify?reportType=fmc-demurrage-detention-invoice-completeness&filename=syn-inv-01-complete-import.html · Content-Type: text/html · 3,442 bytes · sha256 409c2b8b6b3a9e9731ee590dd552e4b4179c284d5aecfbdcee144a78b2720104
Run 1 issued
2026-11-05T23:56:23.275Z
Response
61,183 bytes
sha256
874020b046b1da1b558cf76e75964b473de2d297b4b178570c61de74802f0c98
Run 2 issued
2026-11-05T23:56:27.254Z
Response
61,183 bytes
sha256
76912934d7f656b30818839aa6373493e6394227157ac974efb7159b0539b874
1,817fields compared, path by path, nothing filtered out
1,812identical in both runs
5differ, all listed below

Every field that differs

PathRun 1Run 2Why it moves
requestId18e65cd0-43ab-42c8-8404-4fa5f2761ef2e68f9c05-39b4-4859-9816-2dfa2eb85f5aThe id of the call itself. Each call has its own.
certificate.issuedAt2026-11-05T23:56:23.275Z2026-11-05T23:56:27.254ZThe issue instant.
certificate.barcode…|at=2026-11-05T23:56:23.275Z…|at=2026-11-05T23:56:27.254ZThe barcode ends with the issue instant. Every segment before it is identical.
certificate.answerRefusals.checkedAt2026-11-05T23:56:23.275Z2026-11-05T23:56:27.254ZThe instant the checklist was answered. It is the issue instant.
certificate.signature.signaturerQUj3NgAFK1qzsTCT2RgTpYuUi+i…RQ5V3ZdZ+/lpUeDhENYleAT3RltU…The signature is made over a body that carries the instant, so it moves with it.

Identical in both: all 18 answers, 2 statements, 4 arithmetic checks and 19 slots, the three boundary statements, every rule reference and every derivation id.

An AI system can route its claim through Factum. Factum hands back the answer, the work and a signature, and you can check all three yourself.

The files: run-1.json, run-2.json, public-key.txt, the document, SHA256SUMS.

Look through it

This is run 1, drawn from its signed body. Open any row to look through it: the claim on the surface, the check beneath it, the document's own cells beneath that.

POST /api/tenants/{tenant}/certify?reportType=fmc-demurrage-detention-invoice-completeness&filename=syn-inv-01-complete-import.html
FACTUM
Demurrage / detention invoice — completeness under 46 CFR part 541
fmc-demurrage-detention-invoice-completeness
Issued2026-11-05T23:56:23.275Z Document sha256409c2b8b6b3a9e9731ee590dd552e4b4179c284d5aecfbdcee144a78b2720104

Subject

Document
syn-inv-01-complete-import.html
Kind
html
Size
3,442 bytes
Facts read
31

Verdicts

resolved17 of 18 answersgap1 of 18 answersresolved2 of 2 statementssatisfied4 of 4 arithmetic checksrefused5 sections not written

Answers

the bill of lading numberresolvedPBLU2026034771
Check how this was answered
data point dp-bol-number
fact fact-81627aff4e85c7ca
slot S1
read under Bill of Lading Number / Value
Source table 1, row 2, column 2
Field │ Value Bill of Lading Number │ PBLU2026034771
grid · table 1, row 2, column 2 · syn-inv-01-complete-import.html
the container numberresolvedPBLU4471820
Check how this was answered
data point dp-container-number
fact fact-f6fe79882ec59943
slot S2
read under Container Number / Value
Source table 1, row 3, column 2
Field │ Value Container Number │ PBLU4471820
grid · table 1, row 3, column 2 · syn-inv-01-complete-import.html
the port of dischargeresolvedPort of Long Beach, CA (USLGB)
Check how this was answered
data point dp-port-of-discharge
fact fact-12ab0b7253d2871f
slot S3
read under Port of Discharge / Value
Source table 1, row 4, column 2
Field │ Value Port of Discharge │ Port of Long Beach, CA (USLGB)
grid · table 1, row 4, column 2 · syn-inv-01-complete-import.html
the basis for liabilityresolvedConsignee named on the bill of lading; cargo released to billed party under the same B/L.
Check how this was answered
data point dp-liability-basis
fact fact-f48515756a7ccf2c
slot S4
read under Basis for Liability / Value
Source table 1, row 5, column 2
Field │ Value Basis for Liability │ Consignee named on the bill of lading; cargo released to billed party under the same B/L.
grid · table 1, row 5, column 2 · syn-inv-01-complete-import.html
the invoice dateresolved2026-04-20
Check how this was answered
data point dp-invoice-date
fact fact-7bfbbe12fbaff461
slot S5
read under Invoice Date / Value
Source table 1, row 6, column 2
Field │ Value Invoice Date │ 2026-04-20
grid · table 1, row 6, column 2 · syn-inv-01-complete-import.html
the invoice due dateresolved2026-05-20
Check how this was answered
data point dp-invoice-due-date
fact fact-62384d44b4c3c30d
slot S6
read under Invoice Due Date / Value
Source table 1, row 7, column 2
Field │ Value Invoice Due Date │ 2026-05-20
grid · table 1, row 7, column 2 · syn-inv-01-complete-import.html
the allowed free time (days)resolved4
Check how this was answered
data point dp-free-time-days
fact fact-bd4f9eb23a7e2e36
slot S7
read under Allowed Free Time (Days) / Value
Source table 1, row 8, column 2
Field │ Value Allowed Free Time (Days) │ 4
grid · table 1, row 8, column 2 · syn-inv-01-complete-import.html
the free time start dateresolved2026-04-02
Check how this was answered
data point dp-free-time-start
fact fact-b034e3006ff8980a
slot S8
read under Free Time Start Date / Value
Source table 1, row 9, column 2
Field │ Value Free Time Start Date │ 2026-04-02
grid · table 1, row 9, column 2 · syn-inv-01-complete-import.html
the free time end dateresolved2026-04-05
Check how this was answered
data point dp-free-time-end
fact fact-d034f57c4511bed9
slot S9
read under Free Time End Date / Value
Source table 1, row 10, column 2
Field │ Value Free Time End Date │ 2026-04-05
grid · table 1, row 10, column 2 · syn-inv-01-complete-import.html
the container availability dateresolved2026-04-02
Check how this was answered
data point dp-availability-date
fact fact-1adcd8f059f27946
slot S10
read under Container Availability Date / Value
Source table 1, row 11, column 2
Field │ Value Container Availability Date │ 2026-04-02
grid · table 1, row 11, column 2 · syn-inv-01-complete-import.html
the earliest return dategapno_fact_answers_this_point
Check how this was answered
data point dp-earliest-return
code no_fact_answers_this_point
this result says the earliest return date: no_fact_answers_this_point
remedy not_curable
derivation drv:071ed9039ffbfd065d19f8a9e46c640d
produced by …/certify/data-point-resolution@1
derived from rule:data-point/fmc-demurrage-detention-invoice-completeness%2Fdp-earliest-return
derived from input:document/syn-inv-01-complete-import.html
Source nothing was located
No span. No fact read from this document answers this point, so there are no cells to show.
the dates chargedresolved2026-04-06, 2026-04-07, 2026-04-08, 2026-04-09, 2026-04-10
Check how this was answered
data point dp-charged-dates
fact fact-1f2875fc61c25ccc
slot S12
read under Dates Charged / Value
Source table 1, row 12, column 2
Field │ Value Dates Charged │ 2026-04-06, 2026-04-07, 2026-04-08, 2026-04-09, 2026-04-10
grid · table 1, row 12, column 2 · syn-inv-01-complete-import.html
the total amount dueresolved1375.00
Check how this was answered
data point dp-total-amount-due
fact fact-34fe5c129f430c4f
slot S13
read under Total Amount Due / Amount
Source table 2, row 7, column 5
Date Charged │ Container Number │ Days Charged │ Daily Rate │ Amount Total Amount Due │ · │ · │ · │ 1375.00
grid · table 2, row 7, column 5 · syn-inv-01-complete-import.html
the applicable tariff ruleresolvedPacific Blue Line Tariff PBLU-001, Rule 23-B (Demurrage)
Check how this was answered
data point dp-applicable-rule
fact fact-5f36bcbf6697b961
slot S14
read under Applicable Tariff Rule / Value
Source table 1, row 13, column 2
Field │ Value Applicable Tariff Rule │ Pacific Blue Line Tariff PBLU-001, Rule 23-B (Demurrage)
grid · table 1, row 13, column 2 · syn-inv-01-complete-import.html
the daily rateresolved275.00
Check how this was answered
data point dp-daily-rate
fact fact-d6ee3650e96769fd
slot S15
read under 2026-04-06 PBLU4471820 / Daily Rate
Source table 2, row 2, column 4
Date Charged │ Container Number │ Days Charged │ Daily Rate │ Amount 2026-04-06 │ PBLU4471820 │ 1 │ 275.00 │ 275.00
grid · table 2, row 2, column 4 · syn-inv-01-complete-import.html
the dispute contactresolveddemurrage.disputes@pacificblueline.example +1 (562) 555-0184
Check how this was answered
data point dp-dispute-contact
fact fact-89a93e1c8922b1c7
slot S16
read under Dispute Contact / Value
Source table 1, row 14, column 2
Field │ Value Dispute Contact │ demurrage.disputes@pacificblueline.example +1 (562) 555-0184
grid · table 1, row 14, column 2 · syn-inv-01-complete-import.html
the mitigation request urlresolvedhttps://www.pacificblueline.example/detention-demurrage/mitigation
Check how this was answered
data point dp-dispute-url
fact fact-d86ddafdfbd5f368
slot S17
read under Mitigation Request URL / Value
Source table 1, row 15, column 2
Field │ Value Mitigation Request URL │ https://www.pacificblueline.example/detention-demurrage/mitigation
grid · table 1, row 15, column 2 · syn-inv-01-complete-import.html
the request window (days)resolved30
Check how this was answered
data point dp-dispute-timeframe
fact fact-fd217b1da1d0dd4c
slot S18
read under Request Window (Days) / Value
Source table 1, row 16, column 2
Field │ Value Request Window (Days) │ 30
grid · table 1, row 16, column 2 · syn-inv-01-complete-import.html

Statements

the certification that the charges are consistent with the FMC’s demurrage and detention rulesresolved
Check how this was answered
statement point sp-cert-fmc-rules
slot S19
matches in the document 1
matched form consistent with
matched form Federal Maritime Commission
matched form demurrage and detention
cites 46 CFR part 541 (us-cfr, declared by the document)
cites 46 CFR 545.5 (us-cfr, declared by the document)
Source block 74 of the document
The charges stated on this invoice are consistent with the Federal Maritime Commission’s rules relating to demurrage and detention, including 46 CFR part 541 and 46 CFR 545.5.
text · block 74, characters 0 to 175 of the clause · syn-inv-01-complete-import.html
the certification that the billing party did not cause the chargesresolved
Check how this was answered
statement point sp-cert-no-causation
slot S20
matches in the document 1
matched form did not cause
matched form contribute to
matched form charges
Source block 75 of the document
The billing party’s performance did not cause or contribute to the charges invoiced above.
text · block 75, characters 0 to 90 of the clause · syn-inv-01-complete-import.html

Arithmetic

Does the allowed free time in days equal the span from the free-time start date to the free-time end date?satisfied2026-04-02 to 2026-04-05 inclusive is 4 day(s); the invoice declares 4.
Check how this was answered
arithmetic point ap-arith-free-time-span
cites § 541.6(b)(3)–(5)
derivation drv:8b05c109c31c59b146f853e69e3ba3f4
produced by …/arithmetic/date-span-equals-count@1
rule rule:arithmetic-point/fmc-demurrage-detention-invoice-completeness%2Fap-arith-free-time-span
Source the values this was computed from
the free time start date: 2026-04-02
node:fact-b034e3006ff8980a#value · grid · table 1, row 9, column 2
the free time end date: 2026-04-05
node:fact-d034f57c4511bed9#value · grid · table 1, row 10, column 2
the allowed free time (days): 4
node:fact-bd4f9eb23a7e2e36#value · grid · table 1, row 8, column 2
Does the number of dates charged multiplied by the daily rate equal the total amount due?satisfied5 day(s) charged at 275.00 is 1375.00; the invoice states 1375.00.
Check how this was answered
arithmetic point ap-arith-charge-total
cites § 541.6(c)(1)–(3)
derivation drv:12250656e4fd1dc4dc741516fc95e746
produced by …/arithmetic/count-times-rate-equals-total@1
rule rule:arithmetic-point/fmc-demurrage-detention-invoice-completeness%2Fap-arith-charge-total
Source the values this was computed from
the dates charged: 2026-04-06, 2026-04-07, 2026-04-08, 2026-04-09, 2026-04-10
node:fact-1f2875fc61c25ccc#value · grid · table 1, row 12, column 2
the daily rate: 275.00
node:fact-d6ee3650e96769fd#value · grid · table 2, row 2, column 4
the total amount due: 1375.00
node:fact-34fe5c129f430c4f#value · grid · table 2, row 7, column 5
the container number: PBLU4471820
node:fact-f6fe79882ec59943#value · grid · table 1, row 3, column 2
Was the invoice issued within 30 calendar days of the last date charged?satisfied10 calendar day(s) from the last date charged to 2026-04-20; the limit is 30.
Check how this was answered
arithmetic point ap-arith-issue-window
cites § 541.7(a)
derivation drv:6f3ca516d9982c590e96ab192d858332
produced by …/arithmetic/date-difference-within@1
rule rule:arithmetic-point/fmc-demurrage-detention-invoice-completeness%2Fap-arith-issue-window
Source the values this was computed from
the dates charged: 2026-04-06, 2026-04-07, 2026-04-08, 2026-04-09, 2026-04-10
node:fact-1f2875fc61c25ccc#value · grid · table 1, row 12, column 2
the invoice date: 2026-04-20
node:fact-7bfbbe12fbaff461#value · grid · table 1, row 6, column 2
Does the stated request window give the billed party at least 30 calendar days from the invoice date?satisfiedthe invoice allows 30 day(s) to request mitigation; the minimum is 30.
Check how this was answered
arithmetic point ap-arith-dispute-window
cites § 541.8(a)
derivation drv:a9e911bd4d3414bcb8074f22af24a62c
produced by …/arithmetic/declared-window-at-least@1
rule rule:arithmetic-point/fmc-demurrage-detention-invoice-completeness%2Fap-arith-dispute-window
Source the values this was computed from
the request window (days): 30
node:fact-fd217b1da1d0dd4c#value · grid · table 1, row 16, column 2

Identifier checks

Container Number: iso6346-container check digitinvalidPBLU4471820
Check how this was answered
this result says PBLU4471820, stated by this document under "Container Number", FAILS its iso6346-container check digit - the standard's computation gives 4 and the identifier as stated ends in 0. This is a finding ABOUT THE DOCUMENT: the value is captured exactly as written and is not corrected here, and it was read from the document's own text layer rather than recognised off an image.
computed digit 4
stated digit 0
derivation drv:a27e73ef30d18952f46725fb268bfc39
produced by …/certify/identifier-check-digit@1
Source table 1, row 3, column 2
Field │ Value Container Number │ PBLU4471820
grid · table 1, row 3, column 2 · syn-inv-01-complete-import.html

Sections

Section: What this invoice is aboutrefusedengine_unconfigured
Check how this was answered
code engine_unconfigured
this result says no engine credential is configured, so the engine is not used rather than a response being simulated
remedy declare
declaration needed registerTenantEngine
Source nothing was written
No span. The section was not written, so nothing was read for it. The engine is not simulated.
Section: Timingrefusedengine_unconfigured
Check how this was answered
code engine_unconfigured
this result says no engine credential is configured, so the engine is not used rather than a response being simulated
remedy declare
declaration needed registerTenantEngine
Source nothing was written
No span. The section was not written, so nothing was read for it. The engine is not simulated.
Section: What is owedrefusedengine_unconfigured
Check how this was answered
code engine_unconfigured
this result says no engine credential is configured, so the engine is not used rather than a response being simulated
remedy declare
declaration needed registerTenantEngine
Source nothing was written
No span. The section was not written, so nothing was read for it. The engine is not simulated.
Section: Disputing this invoicerefusedengine_unconfigured
Check how this was answered
code engine_unconfigured
this result says no engine credential is configured, so the engine is not used rather than a response being simulated
remedy declare
declaration needed registerTenantEngine
Source nothing was written
No span. The section was not written, so nothing was read for it. The engine is not simulated.
Section: What the billing party certifiesrefusedengine_unconfigured
Check how this was answered
code engine_unconfigured
this result says no engine credential is configured, so the engine is not used rather than a response being simulated
remedy declare
declaration needed registerTenantEngine
Source nothing was written
No span. The section was not written, so nothing was read for it. The engine is not simulated.

Boundary

CERTIFIED: this report states which of the fields this checklist asks for were LOCATED on the invoice submitted, and names each field that was not. A field reported as not located is reported as missing from this invoice, without a hedge: where 46 CFR part 541 requires a field, it requires it on the invoice itself, and 46 CFR § 541.5 makes the omission of a required field dispositive.

NOT ATTESTED That every field this checklist asks for is required of this particular invoice is not attested; some apply only to an export, or only to an import. What an omission decides about the charges billed is not attested, and whether they are owed is not determined here. That a located value is correct is not attested; it is certified as the invoice states it.

CERTIFIED: the arithmetic below was performed as declared, and every input is the value its source stated, cited by fact id.

NOT ATTESTED That this quantity is meaningful, that it is the right model of anything, or that it predicts anything is not attested. The formula is the operator's declaration, not a finding.

CERTIFIED: nothing under this boundary. This report type declares no citation check.

NOT ATTESTED This certificate does not attest anything about a citation in this document, because no citation was checked.

vd-418b7ced1cea5f8e
Key
A development key minted for this recording. Not the production issuer key.
Algorithm
ed25519
Canonical form
VD-CANON-1
Signature
rQUj3NgAFK1qzsTCT2RgTpYuUi+iIENMiqya5Yw22/6IbSb3HJWpic6/nx7vbPsSDflW2U3mknKQAmrv/I6NBw==
Barcode
479 characters inside the signature, ending at=2026-11-05T23:56:23.275Z. The verifier prints it in full.

A view of the signed body, and nothing more. The window is never the source of truth; the signed certificate is. An identifier check that reads "invalid" is a finding about the document: the fictitious container number does not carry the check digit its own standard computes.

Change a digit

One byte of run 1 is changed: the total amount due, from 1375.00 to 1875.00. The file is still valid JSON. It is the same length. It differs from the original in exactly one character.

The verifier is run on it with the same key.

Does not verifysignature_does_not_verify

The file: run-1-one-digit-changed.json

Recorded outputThe change, and the verifier's output on the changed file (exit code 1).
certificate.answers[12].value
  run-1.json                     "1375.00"
  run-1-one-digit-changed.json   "1875.00"
  byte offset 4,741: "3" became "8"
node factum-verify.mjs run-1-one-digit-changed.json public-key.txt
NOT VERIFIED
  code             signature_does_not_verify
  document keyId   vd-418b7ced1cea5f8e
  your key's keyId vd-418b7ced1cea5f8e
  reason           the signature does not verify over this document under the supplied key. The keyId matched, so the key is the right one: the document does not hold the bytes that were signed.

Verify it without us

Download the Factum Verifier, the two certificates and the key. Run the command. It needs Node 18 or later and nothing else: no install, no network, no account.

Verifiedexit 0

The verifier states its own boundary. A valid signature says the holder of this key signed these bytes. Whose key it is comes from where you obtained it.

Recorded outputThe verifier's output on run 1 (exit code 0). Run 2 reads the same, with its own instant (exit code 0).
node factum-verify.mjs run-1.json public-key.txt
VERIFIED
  keyId            vd-418b7ced1cea5f8e
  canonical bytes  59952
  barcode          … (the signed barcode, 479 characters, printed in full when you run it)
  surface          FULL - the body carries no surface block, so every claim the run captured is on it

  CERTIFIED BY THIS CHECK: this document was signed by the holder of the private half of the
  key you supplied, over the canonical form named in its signature block, and has not been
  altered by one byte since.
  NOT CERTIFIED BY THIS CHECK: that the key you supplied is the operator's. That comes from
  WHERE YOU OBTAINED THE KEY and from nothing in this file - a valid signature under the wrong
  key is exactly what a forgery looks like.
node factum-verify.mjs run-2.json public-key.txt
VERIFIED
  keyId            vd-418b7ced1cea5f8e
  canonical bytes  59952
  barcode          … (the signed barcode, 479 characters, printed in full when you run it)
  surface          FULL - the body carries no surface block, so every claim the run captured is on it

  CERTIFIED BY THIS CHECK: this document was signed by the holder of the private half of the
  key you supplied, over the canonical form named in its signature block, and has not been
  altered by one byte since.
  NOT CERTIFIED BY THIS CHECK: that the key you supplied is the operator's. That comes from
  WHERE YOU OBTAINED THE KEY and from nothing in this file - a valid signature under the wrong
  key is exactly what a forgery looks like.

This is one document under one checklist. Contracts, citations, a tie-out, EDI invoices, a composed checklist, a round trip and a workbook fill are recorded the same way: worked examples. The same certificate is shown as the Console draws it on the Console page.