Filecoin Mirrors and ElevenLabs Voice: Two New Layers on the Trust Stack
Two weeks ago we said Filecoin was deferred and ElevenLabs was presentation, not pillar. Today both ship. This is the deliberate version of that reversal, and what each layer actually does for a user trying to trust an agent that signs receipts on their behalf.
The trust pillar before this week
Every Operator Uplift action that costs money goes through a 402 gate, executes against a real Google API, and produces a receipt signed with an ed25519 keypair held on the server. The public key sits at /api/receipts/public-key. A judge can copy any receipt JSON from /security, canonicalize the inner receipt object, and re-derive the signature locally. That holds together as long as you trust that we did not edit the receipt in our Supabase after signing it.
That last clause is the gap. The signature proves the receipt was signed. The Supabase row proves what we currently say we signed. Those are different statements. A bad-faith operator could re-sign a tampered payload and replace the row, and the new signature would still verify against the same public key. The receipt does not anchor itself.
What Filecoin adds
Every receipt is now pushed to a Filecoin pinning provider (Lighthouse by default) at the moment the cron at /api/cron/filecoin-anchor sweeps. The returned content ID lands on the tool_receipts row as filecoin_cid and surfaces on /security as a clickable filecoin: bafy... link. Anyone, no auth required, can fetch https://<cid>.ipfs.dweb.link and byte-compare the JSON returned by the public gateway against what /api/receipts returns when the user is signed in. If those bytes diverge, the trust chain is broken and we can be caught.
The ed25519 signature still proves authenticity. Filecoin proves the bytes are public, immutable, and independently retrievable. The Solana Merkle root we publish every five receipts proves the order. Together those three primitives mean a receipt cannot be: forged after the fact (ed25519), quietly mutated in our database (Filecoin), or re-ordered to hide a sequence (Solana). No single party owns the trust chain anymore.
Concretely, the code is in lib/filecoin/anchor.ts (Lighthouse + Pinata adapters), the cron is at app/api/cron/filecoin-anchor/route.ts, the migration is lib/filecoin-anchor-migration.sql, and the UI link is in app/(dashboard)/security/page.tsx. The whole thing is two-hours-of-engineering small, which is the right size for a trust primitive: too big and the implementation becomes the risk.
Why we chose Lighthouse first
We support three providers behind one env switch (FILECOIN_PROVIDER): Lighthouse, Pinata, and a Storacha stub. Lighthouse is the default because it ships as a single-token API. Pinata is similar. Storacha uses UCAN delegation, which is the right answer for production but introduces a delegation-proof step that adds friction for the demo window. The codebase lets us swap providers without changing the receipt schema, the signed bytes, or the UI link contract. The choice is operational, not architectural.
What ElevenLabs adds
Voice was off the deck because we did not have a server-side TTS path. Today there is one: POST /api/voice/synth, auth-gated, takes a string, returns an audio/mpeg stream. The demo recording script in docs/demo-recording-script.md includes a copy-pasteable bash loop that posts each of the five voiceover lines and stitches the five MP3 files with 0.3s gaps. The default voice is Rachel (clear narration), overridable per request.
This is not a product surface. It will never appear in /chat or on iMessage. It is a demo-recording tool wired into our own stack so the narration in the demo video is generated by the same provider category we tell users we run on. A judge watching the recording hears ElevenLabs because the script that produced it is the same script anyone with our API key could run. The honesty is in the symmetry, not the novelty.
What this means for an investor reading this
Operator Uplift sells two things: an approval-gated agent that drafts and schedules, and a trust layer that proves what the agent did. Today the trust layer is signed receipts on Supabase, a Merkle root every five receipts on Solana, a public key endpoint anyone can fetch, an on-chain SNS identity tied to that key, and now a Filecoin mirror per receipt that anyone can verify without trusting us. Five primitives, each verifiable from a different vantage point, each minimal enough that a sufficiently motivated user can re-derive every claim themselves.
If the user happens to be a regulator, an auditor, or a buyer doing due diligence on a vendor that touches their email, that pile is the whole pitch. The trust stack is the product. The agent is what justifies caring about the stack.
Want to try it?
Operator Uplift is in private beta. Join the waitlist and we'll let you in.
Try it free