···103103 accountsMu sync.RWMutex
104104 accounts map[string]*atclient.APIClient
105105106106+ // atpClients maps DID -> atp.Client for direct PDS access in tests.
107107+ atpClients map[string]*atp.Client
108108+106109 cleanup []func()
107110}
108111···161164 FeedIndex: feedIndex,
162165 SessionCache: sessionCache,
163166 accounts: make(map[string]*atclient.APIClient),
167167+ atpClients: make(map[string]*atp.Client),
164168 }
165169166170 // Provider routes XRPC calls based on the DID in the request context. The
···246250247251 h.accountsMu.Lock()
248252 h.accounts[acct.DID] = apiClient
253253+ h.atpClients[acct.DID] = atp.NewClient(apiClient, syntax.DID(acct.DID))
249254 h.accountsMu.Unlock()
250255251256 return acct
···347352// through both cache layers down to a real PDS read.
348353func (h *Harness) InvalidateSessionCache(acct TestAccount) {
349354 h.SessionCache.Invalidate(h.SessionIDFor(acct))
355355+}
356356+357357+// PDSGetRecord fetches a single record directly from the PDS via XRPC,
358358+// bypassing all arabica caching and conversion layers. Returns the raw
359359+// record value as stored in the user's repo.
360360+func (h *Harness) PDSGetRecord(acct TestAccount, collection, rkey string) map[string]any {
361361+ h.T.Helper()
362362+ h.accountsMu.RLock()
363363+ client := h.atpClients[acct.DID]
364364+ h.accountsMu.RUnlock()
365365+ require.NotNil(h.T, client, "no atp client for DID %s", acct.DID)
366366+367367+ rec, err := client.GetRecord(context.Background(), collection, rkey)
368368+ require.NoError(h.T, err)
369369+ return rec.Value
370370+}
371371+372372+// PDSListRecords fetches all records in a collection directly from the PDS
373373+// via XRPC. Returns raw record values as stored in the user's repo.
374374+func (h *Harness) PDSListRecords(acct TestAccount, collection string) []map[string]any {
375375+ h.T.Helper()
376376+ h.accountsMu.RLock()
377377+ client := h.atpClients[acct.DID]
378378+ h.accountsMu.RUnlock()
379379+ require.NotNil(h.T, client, "no atp client for DID %s", acct.DID)
380380+381381+ records, err := client.ListAllRecords(context.Background(), collection)
382382+ require.NoError(h.T, err)
383383+384384+ values := make([]map[string]any, len(records))
385385+ for i, r := range records {
386386+ values[i] = r.Value
387387+ }
388388+ return values
350389}
351390352391// Delete sends a DELETE request as the primary account.