Or why I spent my evenings making AI-agent journals impossible to rewrite.
One Tuesday, at 2:37 PM
A disgruntled employee opens the database behind an AI product and
edits one row. The minutes an agent produced yesterday — the ones a client
is about to receive — now say something else. No alert. No trace. The
dashboard shows a pristine history, because the history has been
rewritten.
This isn't a thriller plot. It is the default state of every AI-agent
product shipping today: their logs live in mutable databases, and nothing
exists to prove, after the fact, what the agent actually decided.
I looked for the tool that closes this gap. It didn't exist. So I built it.
It's called NoireBox, it's open source (MIT), and this post is about
what it does, how it does it, and why I believe it's a missing piece.
→ https://slabbdev.github.io/noirebox/
The founding question
After fifteen years of backend engineering — insurance, renewable energy,
real estate — in systems where every decision must be defensible years
later, I asked the question that started everything:
If someone contests a decision made by an AI agent tomorrow, who can
prove it?
Not "who can tell the story". Not "where is it logged". Who can prove it
— to a client, a lawyer, an auditor, a regulator — without trusting the
vendor, the host, or the administrator?
The answer, everywhere, was: nobody. Observability tooling (Langfuse,
LangSmith, Helicone…) is great for debugging what happened — but its
logs stay mutable, and nothing is exportable as evidence. Debugging and
proving are different jobs.
The principle: a proof, not a promise
NoireBox is a tamper-evident journal for AI agents — a flight data
recorder, like the ones in aircraft. Every event (model call, output,
decision, incident) goes through four mechanisms:
1. Hash chaining. Each event's SHA-256 fingerprint includes the previous
event's. Modify, insert, or delete anything and the chain breaks — and the
verifier tells you which event was tampered with. A numbered notebook:
you can't tear out a page without anyone noticing.
2. Signatures. Every fingerprint is signed with Ed25519, using a key
that never leaves the server (chmod 600). Regenerating the whole chain
without the key? The forgery is visible on sight.
3. The outside witness. The detail that kills tampering at the source:
NoireBox has an external timestamp authority (RFC 3161 — the same
protocol notaries and audit firms use) sign the chain head's fingerprint at
time T. Rewriting history afterwards becomes arithmetically impossible:
the old token no longer covers the new head. A journal that timestamps
itself proves nothing — that's the suspect writing its own police report.
4. The third-party-verifiable export. One file, plus a standalone
verifier that anyone runs on their own machine, offline, with no
credentials:
$ python verifier/verifier.py export.json
[✓] INTACT — 3 events verified · attestation valid · anchors checked
And on that Tuesday at 2:37 PM, the same verifier returns a different
verdict:
[3] An attacker rewrites event 2: the minutes now read "REFUSE".
[✗] DETECTED — event 2: invalid hash (content was modified)
(Real output from the repo's tamper demo — not an illustration.)
NoireBox never asks you to trust it. It hands you the dossier, and anyone
recomputes the truth themselves.
What about a whole fleet? One seal, a thousand boxes
Each box seals its own chain head individually. But what if you run 1,200
agents? Aggregated anchoring: the chain heads of N boxes form a Merkle
tree whose root receives a single TSA seal. One seal for the whole
fleet — and each box proves it took part with ~log₂(N) hashes (11 for
1,200), verified offline.
That's the Certificate Transparency model — the system that made HTTPS
certificates auditable worldwide — applied to AI-agent decisions. To my
knowledge, nobody does this.
$ make demo-fleet
[2] Merkle tree: 3 leaves, root ef43f07bbe6b0691…
cr-reunion proof: 2 hashes → ✓ covered
support-juridique proof: 2 hashes → ✓ covered
scoring-credit proof: 2 hashes → ✓ covered
[5] support-juridique regenerates its journal: content rewritten, re-chained cleanly.
[✗] DETECTED — the new head is not covered by the fleet seal.
old head covered: yes; new one: NO
The most important part: the hub doing the aggregation cannot cheat. It can
omit a box (a detectable silence), but it can neither rewrite a sealed
batch nor include a fake head — and it journals the full tree into its
own NoireBox journal. Every member verifies locally, without
contacting anyone. The arithmetic decides.
The guardrail is a plugin (keep yours)
Already running Lakera, Llama Guard, your own LLM-judge, or your own
regexes? Keep them. Prevention is a fungible layer — everyone has their
own, and it will keep changing. Proof is the universal layer.
Journal your solution's verdicts with a single POST /api/v1/events
(type: "incident") and its catches become tamper-evident and
third-party-verifiable, instead of ending up in rewritable app logs. The
bundled detector (regex + micro-model, French and English, ~250 KB per
language) is a working example of the plugin contract, not an
obligation.
The numbers — all reproducible with one command
| Metric | Value | Reproduce with |
|---|---|---|
| Sealing one event (hash + signature + commit) | 0.21 ms |
docs/SPECS.md §6 |
| Full verification of 100 events | 22 ms | verifier/verifier.py |
| Bundled detectors, FR + EN | 293 + 243 KB |
make train · make train-en
|
| Held-out attack sentences (never seen in training) | 12/12 | tests/test_ml_guardrail.py |
| Test suite, re-run on every push | 91 green | GitHub Actions CI |
I imposed one rule on myself: no number that can't be reproduced with one
command. A metric we can't reproduce is unknown — not a rounder number.
That's also why this post contains no "78M+ events", no customer logos, no
testimonials.
What it is not
- Not a blockchain. One issuer, one verifier. Blockchains solve a problem we don't have — consensus among strangers — at a complexity price we refuse to pay.
- Not a certification. A building block that feeds your audits; the exact perimeter is written down in the threat model.
- Not an LLM. A 250 KB specialist detector that sorts sentences into 5 classes, deterministic and testable — not a black box predicting the next token.
Why now
The EU AI
Act (article 12) requires
automatic event logging for high-risk systems. GDPR (art. 5(2), 15/20)
puts the burden of proof on whoever processes the data. ISO 42001 asks for
traceability of AI decisions.
European vendors will have to prove — not promise — what their agents
did. Today, almost none of them can. NoireBox is a sovereign building block:
self-hosted, zero telemetry, keys stay yours. Built in the Vosges mountains
🇫🇷 — yes, proof infrastructure can be built from the mountains.
Try it in three commands
$ git clone https://github.com/slabbdev/noirebox && cd noirebox
$ ./start.sh # 91 green tests + API on :8768 — /docs is live
$ make demo # the model → the journal → the auditor → the attacker
FastAPI, 10 documented routes, a Python SDK, an MCP server (4 tools to plug
your agents in), a DPO-ready PDF export, and a self-hosted TSA (make tsa,
OpenSSL, $0, offline) — because a witness you don't control is a witness
less.
What's next
On the roadmap: a supervision view readable by non-developers, a per-writer
identity field, multi-TSA rotation. The core is MIT, forever —
verification included.
If this resonates, here's what would help the most:
- ⭐ A star on the repo — it sounds silly, but it's what makes a project exist
- 🕵️ Try to break the proof. This is a project whose product is resistance to tampering: the best compliment is an issue describing an attack
- 🔀 Fork it, PR it, question it — the code is deliberately small (one journal, one plugin, one verifier) so it can be read end to end
And if you know a DPO, a CISO, or an AI vendor preparing for article 12,
send them this post — that's exactly who this black box is for.
NoireBox — every AI decision, sealed forever.
Built solo, in the Vosges mountains, between two missions. Code, threat
model and specs:
github.com/slabbdev/noirebox

Top comments (1)
UPDATE 🐳 — it now runs in one command.
No clone, no Python, no setup:
API + OpenAPI docs on :8768/docs, the ML guardrail ships inside the image, and every incident it catches is sealed in the journal before you even open a browser. Pull it anonymously, run it, verify it — that's the whole point of a flight recorder.
Small print, as always: the image is public, the tests are green, the numbers are reproducible. ☕ If the project helps: buymeacoffee.com/samlabbe