Spaces: integration tests against a permissioned-data PDS #93
Labels
No labels
breaking-change
bug
documentation
duplicate
enhancement
good first issue
help wanted
performance
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Grandiras/ATProto.NET#93
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
#89 covers the permissioned data protocol with 212 unit tests, but every one of them stubs the HTTP layer — the cryptographic constructions are pinned against the reference implementation's own outputs, and the wire shape against hand-written JSON. Nothing has ever talked to a real space host.
No PDS release serves
com.atproto.space.*yet; it lives on bluesky-social/atproto#5187. Once a container image exists, add integration tests undertests/ATProtoNet.IntegrationTests/behind aRequiresSpacesFactgate, following theRequiresJetstreamFactpattern inTestInfrastructure.csso they skip in CI rather than fail.Worth covering, because these are the parts a stub cannot check:
getDelegationTokenon the user's PDS, thengetSpaceCredentialon the authority with a real DPoP proof — including that the server accepts thehtuthe SDK sends, which a stub by definition cannot tell us.SpaceDeletedon renewal afterdeleteSpace.createRecord, fetch withgetRepo, and verify the server's commit and index withSpaceRepoCar.Verify. This is the highest-value one — it checks that the SDK's LtHash, commit context encoding, MAC, and canonical DAG-CBOR ordering all agree with a real implementation's, rather than with a reimplementation of the same spec.sinceis no longer serviceable.simplespacepolicy enforcement: a non-member refused undermember-list, and an app refused under#allowList.The reference implementation's own suite (
packages/pds/tests/space/) is a good map of what is worth asserting.Filed by Claude while working on #89 (run).
🤖 On it — follow along in the action run; the reply will link the full session transcript.
📜 Live transcript — updating every ~5 minutes while the task runs.
Multikey, not the legacy verification-method types #98Partialforever for a repo the account never wrote to #99Pushed
claude/issue-93— 26 integration tests that talk to a real space host, plus the docs to stand one up.The host
No PDS release serves
com.atproto.space.*yet, so rather than write the tests blind I built one from atproto#5187 (permissioned-data, still open/WIP) and ran everything against it —pnpm install && pnpm build, then theoauth-provider-uibundle (the PDS won't boot without it), then aTestNetworkNoAppViewonlocalhost:2583with its PLC on:2582. 26 passed; the same suite skips cleanly with no environment set, so CI is unaffected.docs/testing-spaces.mddocuments the exact recipe.What landed
[RequiresSpacesFact]follows theRequiresJetstreamFactpattern — gated onATPROTO_TEST_SPACES=true, plusATPROTO_PDS_ADMIN_PASSWORDandATPROTO_PLC_URL.SpaceNetworkFixtureprovisions three accounts (authority / member / outsider) and deletes them afterwards; each test creates its own space.SpaceCredentialTestshtuthe SDK signs — and the refusals: replayed delegation token, token for another space, proof from another key, proof for another host, bearer presentation,SpaceDeletedon renewal afterdeleteSpace.SpaceRepoSyncTestscreateRecord→getRepo→SpaceRepoCar.Verifyagainst the server's own commit and index (LtHash, commit-context encoding, MAC, canonical DAG-CBOR order all had to agree with a real implementation). Then oplog replay, cursor resumption, divergence → full recovery, and the fallback whensinceisn't serviceable.SimpleSpacePolicyTestsmember-list, app refused under#allowList, the attestation retry firing, revocation at next renewal, repo boundary between co-located accounts.What the real server changed about my expectations
Four tests failed on the first run, all because a stub had let me assume wrongly:
JwtReplayed, notInvalidDelegationToken— the test now accepts either, since the protocol requires the refusal, not a name for it.listRepoOpsfor a member who never wrote answers200 {ops: [], commit: undefined}rather thanRepoNotFound.InvalidClientAttestation, so that test asserts only that the retry fires with the right audience.Two findings outside this task are filed as their own issues: the SDK's DID-document key extraction accepts only
Multikey(upstream accepts the legacyEcdsaSecp256k1VerificationKey2019form too — the fixture carries a workaround that should go away), andSpaceSyncerreportingPartialforever for a repo the account never wrote to.⏱ 19m 9s · 106 turns · tokens: 209.8k in / 77.4k out (+11294.4k cache-read)
📜 Full session transcript
→ Opened PR: #97
→ Filed follow-up issue #98: DID document key extraction accepts only
Multikey, not the legacy verification-method types→ Filed follow-up issue #99: SpaceSyncer reports
Partialforever for a repo the account never wrote to