Moderation, without the policy code

One decision.
Every door it guards.

Ask BitGate what to do with a post, an account, or a listing. Get back an answer built from who the viewer trusts and who you authorized — then apply it. No thresholds to hand-roll, no ban logic scattered through your views.

A decision is not a boolean

Most moderation code collapses everything into hidden: true, then discovers it needs "visible but unbuyable", or "shown but ranked last", and grows a second system to say so. BitGate answers four questions at once, each on its own ladder.

ranking normal → downrank
visibility allow → warn → restrict → hide → deny
interaction allow → require-explicit-action → deny
transaction allow → require-review → deny
Downranking is a sort input, not a filter. A downranked item still appears and can still be acted on. Conflating the two is what makes moderation feel like censorship to the people on the receiving end.

Where the answer comes from

Two independent sources, deliberately kept apart. Being allowed to publish grants no trust; being trusted grants no authority.

People the viewer follows

Reports and mutes count only when they come from the viewer's own trust graph. The same content can be hidden for one person and fine for another — because it genuinely is.

Moderators you authorized

A root key publishes the roster; each moderator publishes under their own key. Revoke a role and their entries stop counting immediately, with nothing to rewrite.

Community curators

Subscribe to someone else's deny list without handing them moderator powers. A curator can contribute names and nothing more.

The viewer's own choices

Personal blocks always win, and "show it anyway" is available wherever your policy permits it. Hidden content says why, instead of silently vanishing.

Pairs with BitLogin

Two halves of the same question. Drop both in and a signed-in visitor gets moderation shaped by their own follow graph.

BitLogin

Who are you?

A login name and password that unlock a portable Nostr identity, with no account server.

+
BitGate

What may you see, and do?

A decision per item, per surface, built from that identity's trust graph and your roster.

const provider = document.querySelector("bitgate-provider");
await provider.ready;
await provider.useSigner(window.nostr);   // BitLogin's NIP-07 provider

Drop it in

One script tag and one element. The provider builds the runtime, loads your administrative state, and every element inside finds it — no wiring code.

<script type="module" src="/vendor/bitgate/bitgate.js"></script>

<bitgate-provider relays="wss://relay.example" root="<root-pubkey>" policy="social">
  <bitgate-veil profile="feed" target-user="<author-pubkey>">
    <img src="thumbnail.jpg" alt="" />
  </bitgate-veil>
</bitgate-provider>
Integration guide → See it running

Built to be borrowed

The engine carries no thresholds of its own. Presets ship in the box so the first run takes one attribute; every number in them is a starting point you are meant to replace.

Headless core

Pure evaluation. No I/O, no browser globals, no dependencies. Runs the same in Node and a browser.

Bring your own relays

A WebSocket transport ships for convenience. Already have a relay pool? Pass an adapter instead.

Your objects, your targets

An adapter says what a product or post is in governance terms. Deny a seller and their whole catalogue goes with them.

Explains itself

Every decision carries stable reason identifiers and the evidence behind it — so appeals are possible.