@fractalai/ai-notary
v0.1.0
Published
The universal notary for AI decisions — post-quantum, on-chain, re-verifiable proof of what any model decided, on what input, when. For any industry: banking, insurance, healthcare, hiring, moderation, trading, crypto/CASP, public sector. Evidence that ou
Maintainers
Readme
@fractalai/ai-notary — The Notary for AI
Seal every AI decision with a re-verifiable, post-quantum, on-chain proof.
When a regulator, auditor, insurer, or opposing counsel asks "prove that this exact model produced this exact decision, for this exact input, at this exact time — and that nobody altered the record afterward," the AI Notary is the answer you hand them. One SDK call turns any AI decision into a Dilithium-2 (NIST FIPS 204) signed, tamper-evident, on-chain-anchored attestation that anyone can re-verify independently — years later, without trusting us.
Provenance and non-repudiation for AI decisions in any industry — SR 11-7 / model-risk governance (in force now) and the EU AI Act Art. 12 record-keeping duty (in force 2 Dec 2027).
Why this exists
- EU AI Act requires high-risk AI systems to automatically record events ("logs") over their lifetime (Art. 12) and deployers to keep them (Art. 26). This record-keeping duty was deferred by the Digital Omnibus (Reg. (EU) 2026/1744) to 2 Dec 2027 — an adoption window, not a same-day cliff — with fines up to 7% of global annual turnover. A log you can silently edit is not evidence; the receipt you adopt now must still verify in 2027 and beyond.
- SR 11-7 (US model risk management) and equivalent expectations demand an auditable, non-repudiable trail of model decisions.
- Ordinary logs, DataRobot/Fiddler reports, and even hash-chained databases can be re-written by whoever controls the database. What survives cross-examination is a cryptographic signature the operator cannot forge or backdate — anchored to an external, immutable time source.
The AI Notary gives you exactly that, at production speed, per decision.
Every industry where AI decides
This is not a finance tool — it is the universal notary for any consequential AI decision. Wherever a model decides something a person will later dispute, appeal, or audit, you need re-verifiable proof of what it decided, on what input, when. That is every industry:
| Industry | The AI decision that gets disputed / audited | |---|---| | Banking / lending | Credit approval, denial, limit — SR 11-7, fair-lending / ECOA adverse-action | | Insurance | Claim approval/denial, underwriting, premium — proof of the basis at decision time | | Healthcare | Triage, prior-authorization, diagnostic support — evidentiary trail for care & liability | | Hiring / HR | Résumé screening, ranking — EEOC / NYC Local Law 144 bias-audit evidence | | Content / platforms | Moderation, takedown, demonetization — appeal-proof record of the call | | Trading / markets | Order, hedge, liquidation, risk-param change — MiFID II / prove the decision to LPs & regulators | | Crypto / CASPs | AML alert, KYC decision, transaction hold — MiCA / DORA tamper-evident audit trail | | Government / public sector | Benefits eligibility, fraud flags — due-process & FOIA-grade evidence | | Autonomous / robotics | A control action taken — a black-box receipt for the incident review |
One SDK call. Any model, any language, any jurisdiction. The receipt is the same primitive everywhere; only the compliance clause it satisfies changes. That universality is the moat: you integrate once and it hardens every AI decision your organization makes.
The self-verifying certificate — the artifact you hand a regulator
Turn any attestation into a gold-sealed, self-contained certificate that carries its own proof and tells the reader how to check it without trusting you:
const att = await notary.attest({ model: 'credit-risk-v4', input, output: 'DECLINE' });
const cert = await notary.certificate(att, { issuedFor: 'Acme Bank' });
fs.writeFileSync('decision-certificate.html', cert.html); // print → PDF, or serve as-isThe .html is fully self-contained (no external assets), embeds the machine-readable proof
(<script type="application/vaid-proof+json">) so anyone can re-verify the post-quantum
signature offline, and shows the on-chain permalink. Want a scan-to-verify QR? Pass any proven
encoder — we deliberately don't bundle a hand-rolled one (a QR that doesn't scan would
betray the promise):
import QRCode from 'qrcode';
const cert = await notary.certificate(att, { qr: (t) => QRCode.toString(t, { type: 'svg' }) });This is what a normal PDF certificate is not: a decorative PDF says "trust me"; this one a regulator, auditor, insurer, lawyer — or a customer who appealed the decision — verifies for themselves. The seal is math, not ink.
The property no one else offers: your evidence outlives your vendor
The receipt carries its own post-quantum public key and canonical bytes, so a third party can
re-verify it independently — even if FractalAI disappears. Your audit trail is never hostage
to a vendor being online. (Fully-offline verification helper: on the roadmap — today verify()
re-checks against the open verifier; the signature itself is already vendor-independent.)
What it proves (and what it does not) — read this
An attestation proves, for a declared decision:
- Provenance — these exact bytes (sha256 of the input, and of the confidence-folded output) were signed by the notary's post-quantum key.
- Integrity — change a single byte of input, output, model id, version, or timestamp and re-verification fails.
- Non-repudiation — the signature is a Dilithium-2 (NIST FIPS 204) signature; the operator cannot later claim the record was forged.
- Freshness — the record is bound to a signing timestamp and best-effort anchored on-chain.
It does NOT prove the decision was correct, fair, unbiased, complete, or that no decision was omitted. It is a notary, not an auditor of reasoning. (Honesty matters more than marketing here — a claim you can't defend in an audit is worse than no claim.)
Dilithium-2 is resistant to all currently known classical and quantum attacks per NIST FIPS 204 — it is not "unbreakable."
The differentiator
| | zkML | DataRobot / Fiddler | AI Notary |
|---|---|---|---|
| Per-decision cost/latency in prod | Impractical (heavy proving) | N/A | Sub-second, cheap |
| Cryptographic non-repudiation | Yes (but proves computation, not signed provenance) | No | Yes (PQC signature) |
| Post-quantum | Rarely | No | Yes (Dilithium-2 / FIPS 204) |
| On-chain anchored (external time) | Optional, costly | No | Yes (best-effort) |
| Sovereign / on-prem deployable | Varies | SaaS | Yes (point baseUrl at your node) |
We are the only stack that combines {sub-second + post-quantum + on-chain + sovereign}. zkML proves a computation was run but is too slow/expensive for per-decision production logging; Fiddler/DataRobot produce monitoring reports but no cryptographic non-repudiation.
Install
npm install @fractalai/ai-notaryRequires Node ≥ 18 (uses the built-in fetch and node:crypto).
Integrate in 5 lines
import { NotaryClient } from '@fractalai/ai-notary';
const notary = new NotaryClient();
const attestation = await notary.attest({
model: 'credit-risk-v4',
modelVersion: '2026-06-20',
input: JSON.stringify(features), // only sha256(input) is signed — raw input is NOT stored
output: 'DECLINE',
confidence: 0.91,
});
// -> persist `attestation` next to your model logs. It is self-contained and re-verifiable.Later, an auditor (or you) re-verifies it — no database trust required:
const { valid, verdict } = await notary.verify(attestation);
// valid === true only if the record is intact AND the PQC signature checks out.
// Tamper one byte -> valid === false.Optionally publish to the ERC-8004 Validation Registry for on-chain discoverability:
const pub = await notary.publishToRegistry(attestation, { chainId: 1 });
// Returns the exact validationResponse(...) call args + ABI + registry address.
// You sign the tx with your own key (you are the validator in ERC-8004 terms).API
new NotaryClient(config?)
| Option | Default | Notes |
|---|---|---|
| baseUrl | https://fractalai.net.co | Point at your sovereign / on-prem node for data residency. |
| apiKey | — | Bearer token for metered enterprise plans. |
| timeoutMs | 15000 | Per-request timeout. |
| maxRetries | 2 | Retries on network / 5xx / 429 (exponential backoff). |
| fetch | global fetch | Inject a custom fetch (proxy, older Node). |
attest(decision): Promise<Attestation>
decision: { model, modelVersion?, input, output, confidence?, agentId?, metadata? }.
confidence(0..1) is folded into the signed output, so it is covered by the signature.agentId, when supplied, also appends the decision to an append-only, chained ledger so the order of a system's decisions is tamper-evident (attestation.ledger).- Only
sha256(input)andsha256(output)are signed and anchored — raw input/output are not stored by the notary. Keep your own copy to reproduce the hashes for an auditor.
verify(attestation): Promise<VerifyResult>
Recomputes the canonical signed message locally and re-checks the Dilithium-2 signature
remotely. valid is true only if both pass. Works against any FractalAI notary node,
including your own — it is a stateless cryptographic check, not a database lookup.
publishToRegistry(attestation, { chainId?, responseUri? }): Promise<RegistryPublication>
Returns the exact ERC-8004 validationResponse(...) arguments, ABI, and registry address. The
SDK does not submit the transaction — you sign it with your own key.
Errors
All errors subclass NotaryError:
NotaryValidationError— bad input (never hits the network).NotaryApiError— non-2xx from the notary (.status,.body).NotaryNetworkError— network/timeout after retries (.cause).
How it works (under the hood)
Every method is a thin, honest wrapper over live FractalAI endpoints:
POST /api/proofmind/sign— the notary signs the canonical decision with its Dilithium-2 key.POST /api/proofmind/attest— an independent verify-before-anchor gate re-checks the signature + agent identity, then anchors on-chain (VAID-1, best-effort).POST /api/proofmind/verify— re-checks the signature statelessly (the auditor's tool).POST /api/blackbox— (optional) appends to the chained ledger whenagentIdis given.POST /api/erc8004/attest— packages the seal for the ERC-8004 Validation Registry.
The canonical message the signature covers is:
base64( JSON.stringify({ agent_id, input_hash, output_hash, model_id, model_version, timestamp }) )where *_hash = sha256hex(...). The SDK reproduces these exact bytes so verification is
independent of us. See examples/python_integration.py for the same flow in Python.
Examples
examples/quickstart.ts— attest, verify, demonstrate tamper-evidence, publish to registry.examples/pipeline-integration.ts— wrap an existing inference pipeline.examples/python_integration.py— the same flow in Python (pip install requests).
Status & honesty
This SDK targets live FractalAI endpoints; the on-chain anchor and the facilitator-settled paid tier depend on server provisioning (see the enterprise page for current availability). The core sign + verify + chained-ledger surface works today. Enterprise SLA, dedicated / sovereign deployment, and volume pricing are offered as a proposal — contact sales.
License
Apache-2.0
