status: active
timestamp: 2026-06-20
tags: [social, lifestream, activitypub, fediverse, mastodon, federation, mirror, primary]
ActivityPub federation mirror
Mirrors lifestream to ActivityPub fediverse — Mastodon, Pleroma, etc
ActivityPub federation mirror
Role
Mirrors the canonical
lifestream JSONL
events from chirag127/oriz-me-data to ActivityPub — the W3C
federation protocol Mastodon, Pleroma, Misskey, and the wider
Fediverse run on. The family hosts a minimal ActivityPub actor at
me.oriz.in/activitypub/actor with an outbox at
me.oriz.in/activitypub/outbox; remote Fediverse users follow
@[email protected] and see the stream natively.
Like the AT Protocol mirror, this is a read of the canonical JSONL — never an origin. If the outbox is wiped, the next rehydrate cycle replays the JSONL into it.
Free tier
- Self-hosted on a Cloudflare Worker
at
me.oriz.in/activitypub/*— already paid-for substrate, $0 marginal cost. - Outbox JSON-LD documents stored in
oriz-me’s staticdist/and served from Cloudflare Pages where possible (cheap, cacheable); inbox / signature verification handled by the Worker. - WebFinger at
me.oriz.in/.well-known/webfinger?resource=acct:[email protected]resolves the actor.
Card / subscription required?
NO. Self-hosted on infrastructure already covered by the Cloudflare-Pages-for-all-sites
- Workers decisions.
How CI / cron consumes it
// scripts/mirror-to-activitypub.ts (sketch)
import { signAndDeliver } from './ap-signing'; // HTTP Signatures (RFC 9421)
for (const event of unmirroredEvents()) {
const note = {
'@context': 'https://www.w3.org/ns/activitystreams',
id: `https://me.oriz.in/activitypub/notes/${event.id}`,
type: 'Note',
attributedTo: 'https://me.oriz.in/activitypub/actor',
content: event.summary,
published: event.occurred_at,
url: event.canonical_url,
to: ['https://www.w3.org/ns/activitystreams#Public'],
};
await signAndDeliver(note, followers());
markMirrored(event.id);
}
Runs hourly via Cloudflare Cron Triggers. HTTP-Signature key pair lives in Doppler; public key embedded in the actor document.
What gets mirrored
- All public-tagged lifestream events from
chirag127/oriz-me-dataper the public/private line policy. - Journal entries not mirrored — gated by the journal-stays-auth-gated decision.
- Age-gated content not mirrored federated.
Alternatives
- AT Protocol mirror — sibling federation; we run both (see lifestream-federation decision).
- Hosted ActivityPub services (e.g. micro.blog) — paid past free trial.
- Nostr — alternative federated protocol; deferred.
- Don’t federate — leaves Fediverse readers unable to follow natively; rejected.
Swap cost
Medium — outbox documents are derived data; the canonical JSONL is
untouched by an ActivityPub redesign. Swapping the self-hosted
implementation for a hosted service (e.g. micro.blog) is a Worker
swap + DNS rebind; mirrored notes are content-addressed by the
JSONL id, so a clean re-publish keeps reader follows intact.
Why this is our pick
Federation reaches a different audience from AT Protocol —
Mastodon and the wider Fediverse aren’t on Bluesky and won’t
follow an AT Protocol-only mirror. Self-hosting on Workers costs
nothing marginal and keeps the family in control of the actor’s
domain identity (@[email protected] is permanent; a hosted
service URL would not be). Pairs with the
AT Protocol mirror — two protocols, one
canonical source — per the
lifestream-federation decision.
Cross-refs
- social services index
- AT Protocol mirror — sibling protocol
- Lifestream federation decision
- Lifestream JSONL is canonical decision
- 100-year strategy locked
- Cloudflare Workers — runs the actor
- Cloudflare Cron Triggers — runs the mirror
- Doppler — secrets source-of-truth
- Public/private line policy
- No card-on-file rule