Summary
Implement an API that resolves a PDS endpoint from a target did, and call it from the two wrappers that currently route to a hardcoded bsky.social host.
Pain points
For the session holder we already know the PDS via session.serviceEndpoint. For an arbitrary target did (someone else's repo) there is no equivalent today, so these wrappers send their request to a fixed Bluesky-operated host instead of the PDS that actually hosts the target repo.
The scaffold for this was already added in #215 (2025-08-22) — public protocol ATIdentityProtocol { func resolvePDSEndpoint(from did: String) async throws -> String } — but no wrapper invokes it, and the affected call-sites still carry the marker:
// TODO: Change this back to "\(self.pdsURL)" once ATIdentityProtocol has been implemented.
Affected wrappers (lexicon-declared "implemented by PDS", accept an arbitrary did / repo, carry the TODO):
| File |
Method |
ComAtprotoRepoDescribeRepoMethod.swift:36 |
describeRepository(_:) |
ComAtprotoRepoListRecordsMethod.swift:43 |
listRecords(from:collection:...) |
Considered Alternatives
- Replace the hardcoded host with
session.serviceEndpoint. Correct only when did == session.sessionDID. Cross-repo reads (e.g. fetching another user's profile record) would then target the caller's PDS, which does not host the target repo, and fail. That is a regression versus today's behaviour, which at least covers entryway-managed cross-repo reads.
- Leave the hardcoded
bsky.social fallback in place. This is the current state. It works via entryway proxying, but that behaviour is a Bluesky infrastructure implementation detail, not an AT Protocol guarantee, and it does not cover self-hosted PDSes.
Is this a breaking change?
No
Additional Context
Summary
Implement an API that resolves a PDS endpoint from a target
did, and call it from the two wrappers that currently route to a hardcodedbsky.socialhost.Pain points
For the session holder we already know the PDS via
session.serviceEndpoint. For an arbitrary targetdid(someone else's repo) there is no equivalent today, so these wrappers send their request to a fixed Bluesky-operated host instead of the PDS that actually hosts the target repo.The scaffold for this was already added in #215 (2025-08-22) —
public protocol ATIdentityProtocol { func resolvePDSEndpoint(from did: String) async throws -> String }— but no wrapper invokes it, and the affected call-sites still carry the marker:Affected wrappers (lexicon-declared "implemented by PDS", accept an arbitrary
did/repo, carry the TODO):ComAtprotoRepoDescribeRepoMethod.swift:36describeRepository(_:)ComAtprotoRepoListRecordsMethod.swift:43listRecords(from:collection:...)Considered Alternatives
session.serviceEndpoint. Correct only whendid == session.sessionDID. Cross-repo reads (e.g. fetching another user's profile record) would then target the caller's PDS, which does not host the target repo, and fail. That is a regression versus today's behaviour, which at least covers entryway-managed cross-repo reads.bsky.socialfallback in place. This is the current state. It works via entryway proxying, but that behaviour is a Bluesky infrastructure implementation detail, not an AT Protocol guarantee, and it does not cover self-hosted PDSes.Is this a breaking change?
No
Additional Context
Sources/ATProtoKit/Utilities/ATIdentityProtocol.swift.ComAtprotoRepoListRecordsMethod.swift:42,ComAtprotoRepoDescribeRepoMethod.swift:35.