AT Protocol firehose mirror (Bluesky)
AT Protocol firehose mirror (Bluesky)
Role
Mirrors the canonical
lifestream JSONL
events from chirag127/oriz-me-data to the AT Protocol — the
federated stack Bluesky runs on. Each event is published as an
AT Protocol record under the family lexicon
me.oriz.in.atproto.lifestream.event. Bluesky and any other
AT Protocol consumer can subscribe via the firehose; readers can
follow @chirag127.oriz.in (DID-handle on the family domain) and
see the stream natively.
The mirror is a read of the canonical JSONL — it never
originates events. If the AT Protocol mirror is wiped, the next
ingest cycle rehydrates it from
chirag127/oriz-me-data/events-YYYY.jsonl.
Free tier
- bsky.social PDS — free unlimited records for personal accounts; rate-limited at the firehose ingress side, well above the family's events/day rate.
- Self-hosted PDS —
@atproto/pdsruns on a free Cloudflare Worker + R2-equivalent storage path; the family already has the substrate. - DID custody: family DID (
did:plc:...) bound to the handlechirag127.oriz.invia DNS TXT record at_atproto.chirag127.oriz.in.
Card / subscription required?
NO. The hosted PDS at bsky.social is free; the self-host path runs on infrastructure already paid for ($0).
How CI / cron consumes it
// scripts/mirror-to-atproto.ts (sketch)
import { AtpAgent } from '@atproto/api';
const agent = new AtpAgent({ service: 'https://bsky.social' });
await agent.login({
identifier: 'chirag127.oriz.in',
password: process.env.ATPROTO_APP_PASSWORD,
});
for (const event of unmirroredEvents()) {
await agent.com.atproto.repo.createRecord({
repo: agent.session!.did,
collection: 'me.oriz.in.atproto.lifestream.event',
record: {
$type: 'me.oriz.in.atproto.lifestream.event',
jsonl_id: event.id,
occurred_at: event.occurred_at,
kind: event.kind,
summary: event.summary,
canonical_url: event.canonical_url,
createdAt: new Date().toISOString(),
},
});
markMirrored(event.id);
}
Runs hourly via Cloudflare Cron Triggers.
Idempotent on the JSONL id — repeated runs no-op.
ATPROTO_APP_PASSWORD lives in Doppler.
What gets mirrored
- All public-tagged lifestream events from
chirag127/oriz-me-dataper the public/private line policy. - Journal entries are not mirrored — gated by the journal-stays-auth-gated decision.
- Age-gated content not mirrored federated — handled per age-gating policy.
Alternatives
- ActivityPub — sibling federation; we run both (see lifestream-federation decision).
- Nostr — alternative federated protocol; deferred.
- RSS only — already produced; federation gives discoverability RSS doesn't.
Swap cost
Medium — the mirror script is decoupled from the canonical store, and the AT Protocol records are derived data. Swapping PDS providers (e.g. bsky.social → self-host) requires re-binding the DID document and re-publishing records; no canonical data is at risk.
Why this is our pick
Federated, free, and the protocol underlying Bluesky — which is
where readers expect to find a "lifestream" in 2026. AT Protocol's
custom-record model fits the family lexicon
(me.oriz.in.atproto.lifestream.event) cleanly. Pairs with
ActivityPub for the Mastodon-flavoured federated audience —
two protocols, one canonical source.