Skip to content

AT Protocol

Dominique Devereaux edited this page Aug 23, 2026 · 1 revision

AT Protocol Integration

The Rift Report (the-rift)

The-rift is the official Veiled Dominion lore/canon bot account on Bluesky. It posts public match announcements when a real remote game concludes, and is the planned home for scheduled Rift Report lore drops and cross-promo posts for Violet's Revenge and Mortis.

Current handle: the-rift.bsky.social Planned handle: @the-rift.veileddominion.loptrlab.com (DNS migration — deferred until consistent posting cadence is established)


How Posting Works

File: atprotoPoster.js (repo root, same level as server.js / gameNamespace.js / roomStore.js)

Trigger: gameOver flips true inside gameNamespace.js's make_move handler for a real remote match. Local play, AI opponent, and Spectator mode do not trigger a post.

Authentication: app-password auth via two Cloud Run environment variables.

Env Var Purpose
BLUESKY_HANDLE The-rift's Bluesky handle
BLUESKY_APP_PASSWORD App password (not the account password)

Rotating the App Password

  1. Log into the-rift's Bluesky account
  2. Settings → App Passwords → revoke the current password → create a new one
  3. In GCP Console → Cloud Run → duet-solo-hackathon → Edit & Deploy New Revision → update BLUESKY_APP_PASSWORD
  4. Deploy. No code change needed.

Note: Never paste the app password directly into Cloud Shell. The char-by-char masking in the test script was bypassed by paste input in a prior incident — the password appeared in terminal scrollback. Always set credentials via the Cloud Run env var UI, not the terminal.


Phase 2: Player Stats Write-Back (Planned, Not Built)

Phase 1 (implemented): the-rift posts a public match announcement.

Phase 2 (planned): write match stats back to each player's actor.rpg.stats record on AT Proto, keyed by their DID. This requires OAuth with PKCE + DPoP — not an app password — because it's a public client-side app with no hideable secret.

Planned implementation location: ibloud/duet_engine_architecture (GitHub Pages), not this repo. OAuth's client_id is a publicly-hosted client-metadata.json URL, which GitHub Pages already provides cleanly.

Implementation plan:

  • Host client-metadata.json on the ibloud GitHub Pages URL
  • Use Bluesky's @atproto/oauth-client-browser package via CDN/ESM (no build step, preserves the repo's no-dependency pitch)
  • Fetch → merge → put into actor.rpg.stats, reusing the read/normalize logic already in duet_engine_architecture/index.html's rpg.actor lookup

Testing plan: Use a throwaway Bluesky account with a disposable rpg.actor record — not a real character, not the-rift — before touching any live data. A merge bug could wipe another game system's data out of a shared actor.rpg.stats record.


What Belongs Here vs. Elsewhere

Topic Location
AT Proto contributor docs (this page) This wiki
ATProto audience-building strategy (feed generator, Ozone labeler, Starter Packs, WhiteWind, Bridgy Fed) Loptr Lab strategy doc (not this repo)
Sealed Deck + player profile schema Player-Profile-Schema

Clone this wiki locally