How We Made Moderation Architecturally Impossible to Skip
By Ronny Cruz Alvarez, founder of Open Feed Network (Candor Network). Solo founder, one production platform, a lot of opinions about write paths.
The bug that convinced me
A few weeks ago I found a bug in my own platform that should keep every trust-and-safety engineer up at night.
Candor screens livestream broadcasts. The broadcaster's identity flows through a JWT so the screening pipeline knows who's streaming. Somewhere in that path, a token verification could fail — and when it did, the code fell back to a default identity. Something like:
jsconst broadcaster = verifiedUser || 'anonymous';
One ||. Written defensively, with good intentions, probably at 1am. The effect: after login, every session silently fell back to anonymous — and anonymous sessions took a code path that bypassed the entire screening stack. Not one classifier. All of them.
Nothing crashed. Nothing logged an error. The moderation system was fully deployed, fully functional, and not running.
Here's the part that matters: this is not an unusual bug. It's the normal failure mode of how the entire industry wires up moderation. And it's why I stopped trusting the standard architecture and rebuilt mine around a single invariant.
The standard architecture is a promise, not a guarantee
Almost every platform — regardless of which moderation vendor they use — works like this:
user content → application code → [call the moderation API, hopefully] → database → feed
Screening and storage are two separate systems, connected by application code. Which means the guarantee "everything gets screened" is only as strong as every code path that could ever write to the database. Every endpoint. Every background job. Every migration script. Every well-intentioned fallback written at 1am.
That guarantee degrades in ways that never show up in a demo:
An engineer adds a new write path and forgets the screening call.
A race condition serves content before the async screen returns.
The moderation service is down and the code "fails open" so users aren't blocked.
A silent fallback (see above) routes around the check entirely.
When something eventually slips through and someone asks "did your moderation run on this post?", all you have is an application log claiming a check happened. Logs get contradicted by other logs. A log is a claim, not a proof.
The invariant
Candor's feed is built on one sentence, and every architectural decision is checked against it:
The database accepts only screened content, because the database forgets nothing.
Two properties, and they force each other:
The store is append-only and immutable. Feed entries form a cryptographic hash-chain: each entry commits the hash of the previous one. Altering any past entry breaks every subsequent hash. Tampering isn't forbidden by policy — it's mathematically detectable.
Because there is no "remove it later," screening must run before the write. On an immutable store, store-then-screen isn't a worse ordering. It's a prohibited one, by definition. The gate is the gatekeeper of an irreversible act.
So the architecture is not "call the moderation API before saving, and we'll code-review to make sure everyone does." It's: the screening gate and the storage write path are the same system. There is no write path into the feed store that hasn't already passed the gate — not as a convention, as a structural property. The || 'anonymous' class of bug can't bypass screening anymore, because there's nothing on the other side of screening to fall through to.
"Wait — immutable? What about legal takedowns?"
This is the first objection everyone raises, and it's a good one. GDPR erasure, court orders, and genuine slip-throughs are real. An immutable feed that can't comply with removal law is a non-starter.
The answer is tombstone redaction. Every entry permanently stores hash(content) — a content commitment — separately from the content payload. When removal is legally required, the payload is deleted, but the entry's slot, its committed hash, and its chain links remain, replaced with a tombstone: entry existed here; removed for reason X; date Y; authority Z.
Chain validation runs against the committed hash, so redacting one entry never breaks verifiability for any other entry. You get both: the content is genuinely gone, and the record that it existed, was screened, and was removed under stated authority is permanent and provable. This was the single most delicate component to build, and it was built and tested first, before anything depended on it.
Fail-closed — but not everywhere, and that's the point
"Fail closed" makes a great slogan and a terrible universal policy. If every screening error blocked every post, one flaky dependency would take the platform down, and the on-call fix would inevitably be… a fail-open patch. Congratulations, you've reinvented the silent bypass, now with extra steps.
So the gate has a severity-tiered failure matrix instead:
Screening pathOn errorWhyTerrorism/violent-extremism contentFail closed — do not storeCatastrophic-harm pathCSAM (hash-matching)Fail closed — do not storeLegal + catastrophicCredibility scoringMay fail open — store without a scoreA missing score degrades a feature; it harms no oneProtected-speech context checkDowngrade-only — can reduce a verdict's severity, can never block, can never skip screeningPrevents over-censorship and prevents "propaganda in costume" from using the context check as a bypass
A missed credibility score and a missed CSAM check are not the same failure. Treating them the same is how you end up either unusable or unsafe.
The companion rule is fail-loud: on Candor, a missing secret at boot is process.exit(1), never a default value. No || 'change-me'. No || 'anonymous'. That rule has personally caught bugs for me that would otherwise have been invisible — including one where an error handler returned a safe-looking "no signal detected" value that was actually masking upstream API failures. A fake all-clear is the worst possible output of a safety system, and the only reliable defense I've found is refusing to let any code path manufacture one.
Honest limitations
A few things this architecture does not magically solve, because architecture posts that claim total victory are lying:
Livestreams can't be pre-screened. You cannot gate live audio/video before it exists. Streams run a different model: real-time transcription fanned out to analyzers, with in-line detection and stream-level response. The immutable-at-ingress guarantee applies to the feed and messages; live media is governed by detection speed, and I'm still actively working that latency down.
The guarantee is structural, and the cryptographic external proof is in development. The hash-chain makes tampering internally detectable today; publishing chain-head hashes to an external anchor — so the proof is verifiable by third parties who don't trust me — is designed and in progress, not done.
Screening quality is still a classifier problem. This architecture guarantees screening ran; it does not make the classifier perfect. What it changes is the failure class: from "the check silently didn't happen" to "the check happened and here's the record."
I'm a solo founder with one production deployment — my own platform, which has been running this in production with a live beta since July 4th. That's the honest scale of the evidence today. Every capability claim I make is verified against the running system with dated probes, not inferred from code or intent; that discipline exists because I once caught my own deployed system diverging from its design, silently, one easy shortcut at a time. Patent analysis on the architecture is underway with counsel.
Why I think this ordering wins
Regulation is moving from "did you moderate?" to "prove you moderated." The EU's DSA already points that way. When that question arrives at your platform, an application log is a weak answer. A storage layer that structurally cannot accept unscreened content — with a tamper-evident chain showing exactly what was screened, when, and what was removed under what authority — is a different kind of answer.
Store-then-screen made sense when storage was mutable and moderation was an afterthought. On an immutable store, screen-before-store isn't a preference. It's the only legal ordering. That constraint turned out to be the most clarifying design decision I've made.
Candor Network is the reference deployment. The individual screening modules (crisis detection, extremism classification, disinformation scoring, sextortion detection) are also available as standalone APIs. If you run a platform or community and any of this maps to a problem you have — or you want to tell me why I'm wrong about the failure matrix — I'm at candortheopenfeednetwork@gmail.com, and I answer everything myself.
Top comments (0)