docs: AT Protocol messaging research (#80) #95
No reviewers
Labels
No labels
auth
bug
composer
correctness
database
durability
enhancement
feeds
interactions
notifications
performance
reliability
safety
security
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
starsetbyte/peregrine!95
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/messaging-research"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Research into AT Protocol messaging (chat.bsky.*) to determine feasibility and implementation path for adding DMs to Peregrine.
Docs
Key findings
chat.bsky.convo.*(23 endpoints)chat.bsky.group.*, 16 endpoints) but not live yet (Discussion #5095)getLog(60s intervals), not WebSocket — DMs are privateatproto-proxyheader routing todid:web:api.bsky.chat#bsky_chattransition:chat.bskyRecommended approach
Phase A (next step): Infrastructure + read-only conversation list
Phase B: Message send, reactions, full chat UI
Phase C: Group chat + push notifications (when server-side lands)
Closes #80
Review verdict: REQUEST CHANGES
The strategic conclusion is sound — Peregrine should pursue
chat.bsky.*, use PDS proxying withdid:web:api.bsky.chat#bsky_chat, and requesttransition:chat.bsky— but this PR is not mergeable or safe to implement from yet.Blocking
PR #95 currently has an empty diff and would merge as a no-op. Head
6632288is already an ancestor ofmain;maincommitted the research and then reverted it inc31980e. Verified: the three-dot diff is 0 bytes and the left/right commit count is2 0. Rebuild the branch from currentmainwith a new commit reintroducing the reviewed docs.The atproto-kotlin examples use class names that do not exist.
03-implementation-path.mdusesChatBskyConvoListConvos.Response,ChatBskyConvoDefsMessageInput, andChatBskyConvoSendMessage.Request. v9.7.5 generates package-scoped types such asio.github.kikin81.atproto.chat.bsky.convo.ListConvosResponse,MessageInput,SendMessageRequest, andGetLogResponse. The examples do not compile as written; add a dependency spike/compile proof.Group-chat status contradicts itself.
01line 4 says group chats launched June 11, while lines 8 and 185–225 say they are not live.02says the official app and Skyscraper have full groups;04says group endpoints return 404. Discussion #5095 still asks for an API timetable. Pick one sourced status and remove unsupported claims. Current upstream has 17 JSON files underchat/bsky/groupincludingdefs.json, not 16; distinguish endpoints from total files.Phase A scope conflicts across documents.
03putsChatPoller/getLogin Phase B;04and the handoff require polling in Phase A. Resolve before task extraction. A read-only list can refresh withlistConvos; incremental event processing is a separate larger slice.The proposed UI state violates the architecture.
ChatUiState.SuccesscontainsLazyPagingItems<Conversation>. That is a Compose UI object created in a composable and must not live in ViewModel state. ExposeFlow<PagingData<Conversation>>or a plain immutable list/state.The “group-prepared” Room design is not group-prepared.
ConversationEntityhard-codes two members while also defining a normalized member table, creating two sources of truth and failing for arbitrary groups. Use the member table as canonical and derive the direct-conversation counterpart.Important
No Room migration plan despite current schema v12. Define
MIGRATION_12_13, register it inALL_MIGRATIONS, commit schema 13 JSON, and execute aMigrationTestHelperdevice test.Reaction storage is malformed.
reactionValue: String? // Latest reaction state, JSON arrayis contradictory and lossy. Defer reactions or model them relationally.OAuth migration can be detected locally.
OAuthSession.grantedScopeis already persisted. Gate Chat from the stored scope and offer reauthorization before provoking a guaranteedBad token scope.Chat routing belongs at the existing routing boundary.
PdsRoutingInterceptoralready rewrites/xrpc/and owns AppView proxy headers. Prefer extending it forchat.bsky.*, or prove separate interceptor ordering, so DPoP signs the final PDS URL.The 60-second cadence needs a source.
getLogexistence is specified; cadence is not. Cite a stable source permalink or label 60 seconds as Peregrine policy.Privacy/retention needs an explicit decision. Room-cached DM plaintext is more sensitive than public timeline cache. Document at-rest behavior, backup/notification-preview policy, logout clearing, and whether Phase A stores full bodies or only previews.
Verified correct
did:web:api.bsky.chat#bsky_chat.transition:chat.bskywithtransition:generic.maxLength10,000 andmaxGraphemes1,000.replyToembeds only one level.io.github.kikin81.atproto:models:9.7.5exist.Required revision path
mainso the PR has a real diff.This branch's tip is an ancestor of
main, but its content was reverted onmainatc31980e. The four research documents (docs/research/01..04-*.md) were independently restored by69adf55and are onmaintoday, with a sourced re-verification table added to04-decisions.mdrecording the four AT Protocol sources checked on 2026-07-25. Branch deleted; the content lives onmain.Reconciled in
docs/reviews/2026-07-25-branch-pr-reconciliation.md, which landed onmainvia #103.Pull request closed