Social Annotations in the Atmosphere
Comprehensive Simplification & Reliability Plan#
Based on the Oracle's review, this plan focuses on simplifying the architecture by enforcing "Storage as Source of Truth," standardizing messaging, and aligning with AT Protocol patterns.
Phase 1: Core Protocol & Runtime Definition#
Goal: Establish a shared vocabulary for all components to prevent drift and ad-hoc logic.
- Create
packages/core/src/constants.ts- Move Protocol Constants:
ANNOTATION_COLLECTION,COMMENT_COLLECTION. - Define Storage Keys:
STORAGE_KEY_PREFIX(e.g.,seams:),ANNOTATIONS_KEY_PREFIX. - Define XRPC Endpoints:
XRPC_CREATE_RECORD,XRPC_GET_RECORD.
- Move Protocol Constants:
- Create
packages/core/src/messages.ts- Define a strict Union Type for all internal messages:
SYNC_CACHE: Trigger a sync from backend to storage.GET_STATE: Request current selection/auth state.SELECTION_CHANGED: Notify that user selected text.PAGE_URL_CHANGED: Notify that the URL changed (SPA nav).LOGIN / LOGOUT: Auth state changes.
- Define a strict Union Type for all internal messages:
- Refactor
packages/core/src/types.ts- Ensure
Annotationtype clearly distinguishes between "UI Shape" and "ATProto Record Shape" (if they differ). - Add strict types for
Selectors.
- Ensure
Phase 2: Unifying the Message Bus#
Goal: Remove ad-hoc sendMessage calls and use a type-safe wrapper.
- Create
Messengerclass in Core- A simple wrapper around
browser.runtime.sendMessage(Extension) andpostMessage(Proxy). - Methods:
send(msg: Message),on(type, handler).
- A simple wrapper around
- Refactor Extension to use
Messenger- Update
background/extension.tsandcontent/extension.ts. - Remove any raw string message matching.
- Update
- Refactor Proxy to use
Messenger- Update
via-client/main.tsandvia-client/sidebar.tsto match the same protocol.
- Update
Phase 3: Storage-First Enforcement#
Goal: Decouple UI from Network. The UI should only render what is in Storage.
- Audit & Refactor
ContentScript- Verify it only renders in response to
storage.onChanged. - Remove any direct "fetch and render" logic triggered by page load (replace with "load from storage, then trigger background sync").
- Verify it only renders in response to
- Audit & Refactor
Sidebar- Ensure it reads annotations from storage, not from a message response.
- Standardize Sync Logic
- Extension: Ensure
BackgroundWorkeris the only writer toannotations:*storage keys. - Proxy: Create a simple "Worker" in the client script (or sidebar) that polls the backend and writes to
localStorage.
- Extension: Ensure
Phase 4: AT Protocol & Backend Alignment#
Goal: Treat the PDS/Backend interaction as a stable API surface.
- Refactor
packages/core/src/pds/index.ts- Use constants from
constants.ts. - Ensure
createAnnotationuses the strict Record type.
- Use constants from
- Align Backend (
server/)- Update Go structs to match the Core
Annotationtypes/constants (manually for now, but strict). - Ensure the "Index" endpoint expects exactly what the frontend sends.
- Update Go structs to match the Core
Phase 5: Documentation#
- Update
README.mdor createARCHITECTURE.md- Document the "Storage Flow" (Diagrams from Oracle).
- Document the "Message Vocabulary".