type: decision
status: active
timestamp: 2026-06-20
tags: [decisions, architecture, lifestream, federation, atproto, bluesky, activitypub, fediverse]
status: active
timestamp: 2026-06-20
tags: [decisions, architecture, lifestream, federation, atproto, bluesky, activitypub, fediverse]
Lifestream federation — mirror to BOTH AT Protocol and ActivityPub
oriz-me JSONL canonical, AT Protocol mirror under me.oriz.in.atproto AND ActivityPub outbox at me.oriz.in/activitypub/outbox. Single source, two protocols.
Lifestream federation — mirror to BOTH AT Protocol and ActivityPub
Decision
The canonical
lifestream JSONL in chirag127/oriz-me-data
stays the single source of truth. It is mirrored to two
federated protocols, in parallel, on every cron tick:
- AT Protocol — records published under the family lexicon
me.oriz.in.atproto.lifestream.event, attributed todid:plc:...bound to the handlechirag127.oriz.in. Bluesky and any other AT Protocol consumer can subscribe. Seeservices/business/social/atproto-firehose.md. - ActivityPub —
Noteobjects published to the outbox athttps://me.oriz.in/activitypub/outbox; actor atme.oriz.in/activitypub/actor. Mastodon / Pleroma / Misskey / the wider Fediverse can follow@[email protected]natively. Seeservices/business/social/activitypub.md.
Both mirrors are derived data. They are idempotent on the JSONL
event id. If either mirror is wiped, the next rehydrate cycle
replays the canonical JSONL into it — no data is at risk.
Why
- Different audiences live on different federations. Bluesky’s network and the wider Fediverse barely overlap in 2026; an AT Protocol-only mirror leaves Mastodon followers without a feed, and the reverse leaves Bluesky followers out. Both is the only way to be reachable everywhere readers already are.
- Single canonical source preserves the
100-year strategy. No
federation client becomes the source of truth — vendor / protocol
format risk stays bounded by the
JSONL canonical decision. If
AT Protocol or ActivityPub disappears in 2046, the JSONL still
parses with
jq. - Cost is zero. AT Protocol PDS is free on bsky.social or self-hostable on already-paid Workers; ActivityPub is self-hosted on the same Workers + Pages substrate. No new vendor, no card.
- Domain identity stays family-owned.
chirag127.oriz.in(AT handle, DNS-bound) and@[email protected](ActivityPub actor) both live on the family domain — readers’ follow relationships survive any provider swap.
Implications
Architecture
- Two mirror scripts, both reading from
chirag127/oriz-me-datavia the canonical-store-jsonl architecture:scripts/mirror-to-atproto.ts— pushes new JSONL events as AT Protocol records.scripts/mirror-to-activitypub.ts— pushes new JSONL events as ActivityPubNotes, signs with HTTP Signatures, delivers to follower inboxes.
- Both run hourly via
Cloudflare Cron Triggers.
Idempotent on JSONL
id; repeated runs no-op. - The Hono Worker at
api.oriz.inexposes the ActivityPub actor / inbox / outbox routes mounted underme.oriz.in/activitypub/*via the cross-host umbrella perhono-worker-api-umbrella. - WebFinger lives at
me.oriz.in/.well-known/webfinger, served by the same Worker.
Identity bindings
- AT Protocol DID custody: family DID (
did:plc:...), bound to handlechirag127.oriz.invia DNS TXT record at_atproto.chirag127.oriz.in. Cloudflare DNS handles the record per the DNS decision. - ActivityPub actor key pair: RSA / Ed25519 stored in Doppler; public key embedded in the actor document; private key never leaves the Worker binding.
What gets federated
- Public-tagged events only. Per the public/private line policy and the journal-stays-auth-gated decision, journal entries are NOT federated. Age-gated content per age-gating policy is NOT federated.
- The mirror scripts read the
visibilitytag on each JSONL event and skip non-public events.
What we don’t do
- No origination on either federation. Posting directly into Bluesky’s web app or a Mastodon client is rejected — the JSONL must always be the origin so the canonical store stays authoritative. Replies received via either federation are fetched into the JSONL by the same cron, then re-mirrored to the other federation.
- No Nostr mirror. Deferred — covered by the AT + AP pair for now; revisit when Nostr’s reader population shifts.
- No paid hosted federation gateway (Bridgy Fed, micro.blog, Buttondown federation). Self-hosting the ActivityPub Worker is free.
- No federation of journal / age-gated / private events. Filtered at mirror time — never sent into either protocol.
Cross-refs
- AT Protocol mirror service entry
- ActivityPub mirror service entry
- social services index
- Lifestream JSONL is canonical (anchor decision)
- 100-year strategy locked
- Journal stays auth-gated
- Public/private line policy
- Hono Worker API umbrella
- Spaceship registrar + Cloudflare DNS
- Cloudflare Cron Triggers
- Doppler — secrets source-of-truth
- No card-on-file rule