Repository: bluesky-social/indigo

Issue:
rename some of the atproto packages
Some of these are just too much of a naming collision, either with stdlib packages or obvious/idiomatic variable names.

Proposed:

- `atproto/data` -> `atproto/atdata`
- `atproto/client` -> `atproto/atclient`
- `atproto/crypto` -> `atproto/atcrypto`
- `atproto/label` -> `atproto/labeling`

I think `auth`, `identity`, `lexicon`, and `syntax` are fine. I'm not sure about `repo`. I don't think we should go for consistency with `ateverything`.

There can be a transition period where the old symbols are re-exported.

Hints from issue comments:
@oppiliappan: i personally do not mind the existing nomenclature, the onus is on language tooling to get the imports right (gopls could suggest `atprotocrypto "github.com/.../atproto/crypto"` if `crypto is already imported). @iameli: Seems like a solid collection. `data` feels like an especially rough one to accidentally shadow. 

I will say that you also do have two packages named `util`, and all of the Streamplace code and almost all of the indigo code IIRC imports `lex/util` as `lexutil`, maybe another one that could be codified @bnewbold: I made a branch with the changes and I like them, will probably roll forward with this. Had a number of instances where I was already importing as `atdata` for example.

I think just ripping the band-aid is the right move, instead of trying to re-export the old methods under the old package names, that could cause confusion. This will be a bit disruptive but I don't think too bad.@verdverm: please no, this is unnecessary with import declarations

guess I'm too late to comment on breaking changes

Solution patch:
diff --git a/HACKING.md b/HACKING.md
index 34b05546..76cb68d3 100644
--- a/HACKING.md
+++ b/HACKING.md
@@ -26,10 +26,10 @@ Packages:
     - `api/bsky`: generated types for `app.bsky` lexicon
     - `api/chat`: generated types for `chat.bsky` lexicon
     - `api/ozone`: generated types for `tools.ozone` lexicon
-- `atproto/crypto`: cryptographic helpers (signing, key generation and serialization)
+- `atproto/atcrypto`: cryptographic helpers (signing, key generation and serialization)
 - `atproto/syntax`: string types and parsers for identifiers, datetimes, etc
 - `atproto/identity`: DID and handle resolution
-- `atproto/data`: helpers for atproto data as JSON or CBOR with unknown schema
+- `atproto/atdata`: helpers for atproto data as JSON or CBOR with unknown schema
 - `atproto/lexicon`: lexicon validation of generic data
 - `atproto/repo`: repo and MST implementation
 - `automod`: moderation and anti-spam rules engine
diff --git a/README.md b/README.md
index 51551a28..88ad2cd8 100644
--- a/README.md
+++ b/README.md
@@ -25,7 +25,7 @@ Some Bluesky software is developed in Typescript, and lives in the [bluesky-soci
 | ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
 | `api/atproto`: generated types for `com.atproto.*` Lexicons  | [![PkgGoDev](https://pkg.go.dev/badge/mod/github.com/bluesky-social/indigo/api/atproto)](https://pkg.go.dev/mod/github.com/bluesky-social/indigo/api/atproto)           |
 | `api/bsky`: generated types for `app.bsky.*` Lexicons        | [![PkgGoDev](https://pkg.go.dev/badge/mod/github.com/bluesky-social/indigo/api/bsky)](https://pkg.go.dev/mod/github.com/bluesky-social/indigo/api/bsky)                 |
-| `atproto/crypto`: crytographic signing and key serialization | [![PkgGoDev](https://pkg.go.dev/badge/mod/github.com/bluesky-social/indigo/atproto/crypto)](https://pkg.go.dev/mod/github.com/bluesky-social/indigo/atproto/crypto)     |
+| `atproto/atcrypto`: crytographic signing and key serialization | [![PkgGoDev](https://pkg.go.dev/badge/mod/github.com/bluesky-social/indigo/atproto/atcrypto)](https://pkg.go.dev/mod/github.com/bluesky-social/indigo/atproto/atcrypto)     |
 | `atproto/identity`: DID and handle resolution                | [![PkgGoDev](https://pkg.go.dev/badge/mod/github.com/bluesky-social/indigo/atproto/identity)](https://pkg.go.dev/mod/github.com/bluesky-social/indigo/atproto/identity) |
 | `atproto/syntax`: string types and parsers for identifiers   | [![PkgGoDev](https://pkg.go.dev/badge/mod/github.com/bluesky-social/indigo/atproto/syntax)](https://pkg.go.dev/mod/github.com/bluesky-social/indigo/atproto/syntax)     |
 | `atproto/lexicon`: schema validation of data                 | [![PkgGoDev](https://pkg.go.dev/badge/mod/github.com/bluesky-social/indigo/atproto/lexicon)](https://pkg.go.dev/mod/github.com/bluesky-social/indigo/atproto/lexicon)     |
diff --git a/atproto/client/admin_auth.go b/atproto/atclient/admin_auth.go
similarity index 96%
rename from atproto/client/admin_auth.go
rename to atproto/atclient/admin_auth.go
index bab09e87..b80ed078 100644
--- a/atproto/client/admin_auth.go
+++ b/atproto/atclient/admin_auth.go
@@ -1,4 +1,4 @@
-package client
+package atclient
 
 import (
 	"net/http"
diff --git a/atproto/client/apiclient.go b/atproto/atclient/apiclient.go
similarity index 99%
rename from atproto/client/apiclient.go
rename to atproto/atclient/apiclient.go
index 3811f7ca..0a0fe732 100644
--- a/atproto/client/apiclient.go
+++ b/atproto/atclient/apiclient.go
@@ -1,4 +1,4 @@
-package client
+package atclient
 
 import (
 	"bytes"
diff --git a/atproto/client/apierror.go b/atproto/atclient/apierror.go
similarity index 97%
rename from atproto/client/apierror.go
rename to atproto/atclient/apierror.go
index a319362c..f0003960 100644
--- a/atproto/client/apierror.go
+++ b/atproto/atclient/apierror.go
@@ -1,4 +1,4 @@
-package client
+package atclient
 
 import (
 	"fmt"
diff --git a/atproto/client/apirequest.go b/atproto/atclient/apirequest.go
similarity index 99%
rename from atproto/client/apirequest.go
rename to atproto/atclient/apirequest.go
index 36e7258a..b676ad83 100644
--- a/atproto/client/apirequest.go
+++ b/atproto/atclient/apirequest.go
@@ -1,4 +1,4 @@
-package client
+package atclient
 
 import (
 	"context"
diff --git a/atproto/client/cmd/atp-client-demo/main.go b/atproto/atclient/cmd/atp-client-demo/main.go
similarity index 90%
rename from atproto/client/cmd/atp-client-demo/main.go
rename to atproto/atclient/cmd/atp-client-demo/main.go
index 11a12b2e..e2223e3c 100644
--- a/atproto/client/cmd/atp-client-demo/main.go
+++ b/atproto/atclient/cmd/atp-client-demo/main.go
@@ -8,7 +8,7 @@ import (
 	"os"
 
 	comatproto "github.com/bluesky-social/indigo/api/agnostic"
-	"github.com/bluesky-social/indigo/atproto/client"
+	"github.com/bluesky-social/indigo/atproto/atclient"
 	"github.com/bluesky-social/indigo/atproto/identity"
 	"github.com/bluesky-social/indigo/atproto/syntax"
 
@@ -120,7 +120,7 @@ func main() {
 	app.RunAndExitOnError()
 }
 
-func getFeed(ctx context.Context, c *client.APIClient) error {
+func getFeed(ctx context.Context, c *atclient.APIClient) error {
 	params := map[string]any{
 		"actor":       "atproto.com",
 		"limit":       2,
@@ -141,7 +141,7 @@ func getFeed(ctx context.Context, c *client.APIClient) error {
 	return nil
 }
 
-func listRecords(ctx context.Context, c *client.APIClient) error {
+func listRecords(ctx context.Context, c *atclient.APIClient) error {
 
 	list, err := comatproto.RepoListRecords(ctx, c, "app.bsky.actor.profile", "", 10, "did:plc:ewvi7nxzyoun6zhxrhs64oiz", false)
 	if err != nil {
@@ -159,7 +159,7 @@ func listRecords(ctx context.Context, c *client.APIClient) error {
 func runGetFeedPublic(cctx *cli.Context) error {
 	ctx := cctx.Context
 
-	c := client.APIClient{
+	c := atclient.APIClient{
 		Host: cctx.String("host"),
 	}
 
@@ -169,7 +169,7 @@ func runGetFeedPublic(cctx *cli.Context) error {
 func runListRecordsPublic(cctx *cli.Context) error {
 	ctx := cctx.Context
 
-	c := client.APIClient{
+	c := atclient.APIClient{
 		Host: cctx.String("host"),
 	}
 
@@ -186,7 +186,7 @@ func runLoginAuth(cctx *cli.Context) error {
 
 	dir := identity.DefaultDirectory()
 
-	c, err := client.LoginWithPassword(ctx, dir, *atid, cctx.String("password"), "", nil)
+	c, err := atclient.LoginWithPassword(ctx, dir, *atid, cctx.String("password"), "", nil)
 	if err != nil {
 		return err
 	}
@@ -215,7 +215,7 @@ func runGetFeedAuth(cctx *cli.Context) error {
 
 	dir := identity.DefaultDirectory()
 
-	c, err := client.LoginWithPassword(ctx, dir, *atid, cctx.String("password"), "", nil)
+	c, err := atclient.LoginWithPassword(ctx, dir, *atid, cctx.String("password"), "", nil)
 	if err != nil {
 		return err
 	}
@@ -227,7 +227,7 @@ func runGetFeedAuth(cctx *cli.Context) error {
 func runLookupAdmin(cctx *cli.Context) error {
 	ctx := cctx.Context
 
-	c := client.NewAdminClient(cctx.String("host"), cctx.String("admin-password"))
+	c := atclient.NewAdminClient(cctx.String("host"), cctx.String("admin-password"))
 
 	var d json.RawMessage
 	params := map[string]any{
diff --git a/atproto/client/doc.go b/atproto/atclient/doc.go
similarity index 99%
rename from atproto/client/doc.go
rename to atproto/atclient/doc.go
index 67ea70f9..47a5643b 100644
--- a/atproto/client/doc.go
+++ b/atproto/atclient/doc.go
@@ -18,4 +18,4 @@ In theory, the [http.RoundTripper] interface could have been used instead of [Au
 
 This package tries to use minimal dependencies beyond the Go standard library, to make it easy to reference as a dependency. It does require the [github.com/bluesky-social/indigo/atproto/syntax] and [github.com/bluesky-social/indigo/atproto/identity] sibling packages. In particular, this package does not include any auth methods requiring JWTs, to avoid adding any specific JWT implementation as a dependency.
 */
-package client
+package atclient
diff --git a/atproto/client/lexclient.go b/atproto/atclient/lexclient.go
similarity index 99%
rename from atproto/client/lexclient.go
rename to atproto/atclient/lexclient.go
index 91f5b05e..c72d814a 100644
--- a/atproto/client/lexclient.go
+++ b/atproto/atclient/lexclient.go
@@ -1,4 +1,4 @@
-package client
+package atclient
 
 import (
 	"bytes"
diff --git a/atproto/client/params.go b/atproto/atclient/params.go
similarity index 98%
rename from atproto/client/params.go
rename to atproto/atclient/params.go
index 46324874..cefba522 100644
--- a/atproto/client/params.go
+++ b/atproto/atclient/params.go
@@ -1,4 +1,4 @@
-package client
+package atclient
 
 import (
 	"encoding"
diff --git a/atproto/client/password_auth.go b/atproto/atclient/password_auth.go
similarity index 99%
rename from atproto/client/password_auth.go
rename to atproto/atclient/password_auth.go
index 7e92196a..3f3af5d2 100644
--- a/atproto/client/password_auth.go
+++ b/atproto/atclient/password_auth.go
@@ -1,4 +1,4 @@
-package client
+package atclient
 
 import (
 	"context"
diff --git a/atproto/crypto/cmd/atp-crypto/main.go b/atproto/atcrypto/cmd/atp-crypto/main.go
similarity index 86%
rename from atproto/crypto/cmd/atp-crypto/main.go
rename to atproto/atcrypto/cmd/atp-crypto/main.go
index 9a733542..59f6a32c 100644
--- a/atproto/crypto/cmd/atp-crypto/main.go
+++ b/atproto/atcrypto/cmd/atp-crypto/main.go
@@ -5,7 +5,7 @@ import (
 	"log/slog"
 	"os"
 
-	"github.com/bluesky-social/indigo/atproto/crypto"
+	"github.com/bluesky-social/indigo/atproto/atcrypto"
 
 	"github.com/urfave/cli/v2"
 )
@@ -40,13 +40,13 @@ func main() {
 
 func runGenerate(cctx *cli.Context) error {
 	if cctx.Bool("k256") {
-		priv, err := crypto.GeneratePrivateKeyK256()
+		priv, err := atcrypto.GeneratePrivateKeyK256()
 		if err != nil {
 			return err
 		}
 		fmt.Println(priv.Multibase())
 	} else {
-		priv, err := crypto.GeneratePrivateKeyP256()
+		priv, err := atcrypto.GeneratePrivateKeyP256()
 		if err != nil {
 			return err
 		}
diff --git a/atproto/crypto/docs.go b/atproto/atcrypto/docs.go
similarity index 86%
rename from atproto/crypto/docs.go
rename to atproto/atcrypto/docs.go
index a9bea215..20f7602a 100644
--- a/atproto/crypto/docs.go
+++ b/atproto/atcrypto/docs.go
@@ -1,4 +1,4 @@
-// Package crypto provides cryptographic keys and operations, as used in atproto (the protocol)
+// Package atcrypto provides cryptographic keys and operations, as used in atproto (the protocol)
 //
 // This package attempts to abstract away the specific curves, compressions, signature variations, and other implementation details. The goal is to provide as few knobs and options as possible when working with this library. Use of cryptography in atproto is specified in https://atproto.com/specs/cryptography.
 //
@@ -8,4 +8,4 @@
 //   - K-256/secp256r1, internally implemented using https://gitlab.com/yawning/secp256k1-voi
 //
 // "Low-S" signatures are enforced for both key types, both when creating signatures and during verification, as required by the atproto specification.
-package crypto
+package atcrypto
diff --git a/atproto/crypto/jwk.go b/atproto/atcrypto/jwk.go
similarity index 99%
rename from atproto/crypto/jwk.go
rename to atproto/atcrypto/jwk.go
index 44956610..f51b725a 100644
--- a/atproto/crypto/jwk.go
+++ b/atproto/atcrypto/jwk.go
@@ -1,4 +1,4 @@
-package crypto
+package atcrypto
 
 import (
 	"crypto/ecdsa"
diff --git a/atproto/crypto/k256.go b/atproto/atcrypto/k256.go
similarity index 99%
rename from atproto/crypto/k256.go
rename to atproto/atcrypto/k256.go
index c04b5883..c89bf2f1 100644
--- a/atproto/crypto/k256.go
+++ b/atproto/atcrypto/k256.go
@@ -1,4 +1,4 @@
-package crypto
+package atcrypto
 
 import (
 	"crypto"
diff --git a/atproto/crypto/keys.go b/atproto/atcrypto/keys.go
similarity index 99%
rename from atproto/crypto/keys.go
rename to atproto/atcrypto/keys.go
index c9dbfa96..6f43b655 100644
--- a/atproto/crypto/keys.go
+++ b/atproto/atcrypto/keys.go
@@ -1,4 +1,4 @@
-package crypto
+package atcrypto
 
 import (
 	"errors"
diff --git a/atproto/crypto/p256.go b/atproto/atcrypto/p256.go
similarity index 99%
rename from atproto/crypto/p256.go
rename to atproto/atcrypto/p256.go
index f0e47ffd..09ad51df 100644
--- a/atproto/crypto/p256.go
+++ b/atproto/atcrypto/p256.go
@@ -1,4 +1,4 @@
-package crypto
+package atcrypto
 
 import (
 	"crypto/ecdh"
diff --git a/atproto/crypto/p256_lowS.go b/atproto/atcrypto/p256_lowS.go
similarity index 97%
rename from atproto/crypto/p256_lowS.go
rename to atproto/atcrypto/p256_lowS.go
index abc4eafb..9d5b6e05 100644
--- a/atproto/crypto/p256_lowS.go
+++ b/atproto/atcrypto/p256_lowS.go
@@ -1,4 +1,4 @@
-package crypto
+package atcrypto
 
 import (
 	"crypto/elliptic"
diff --git a/atproto/data/blob.go b/atproto/atdata/blob.go
similarity index 99%
rename from atproto/data/blob.go
rename to atproto/atdata/blob.go
index db3d12f1..3537e27c 100644
--- a/atproto/data/blob.go
+++ b/atproto/atdata/blob.go
@@ -1,4 +1,4 @@
-package data
+package atdata
 
 import (
 	"bytes"
diff --git a/atproto/data/bytes.go b/atproto/atdata/bytes.go
similarity index 98%
rename from atproto/data/bytes.go
rename to atproto/atdata/bytes.go
index b849db5f..dcee4aed 100644
--- a/atproto/data/bytes.go
+++ b/atproto/atdata/bytes.go
@@ -1,4 +1,4 @@
-package data
+package atdata
 
 import (
 	"encoding/base64"
diff --git a/atproto/data/cbor_gen.go b/atproto/atdata/cbor_gen.go
similarity index 99%
rename from atproto/data/cbor_gen.go
rename to atproto/atdata/cbor_gen.go
index 18280b70..a499d6ad 100644
--- a/atproto/data/cbor_gen.go
+++ b/atproto/atdata/cbor_gen.go
@@ -1,6 +1,6 @@
 // Code generated by github.com/whyrusleeping/cbor-gen. DO NOT EDIT.
 
-package data
+package atdata
 
 import (
 	"fmt"
@@ -264,7 +264,7 @@ func (t *BlobSchema) MarshalCBOR(w io.Writer) error {
 		return err
 	}
 
-	// t.Ref (data.CIDLink) (struct)
+	// t.Ref (atdata.CIDLink) (struct)
 	if len("ref") > 1000000 {
 		return xerrors.Errorf("Value in field \"ref\" was too long")
 	}
@@ -387,7 +387,7 @@ func (t *BlobSchema) UnmarshalCBOR(r io.Reader) (err error) {
 		}
 
 		switch string(nameBuf[:nameLen]) {
-		// t.Ref (data.CIDLink) (struct)
+		// t.Ref (atdata.CIDLink) (struct)
 		case "ref":
 
 			{
diff --git a/atproto/data/cidlink.go b/atproto/atdata/cidlink.go
similarity index 99%
rename from atproto/data/cidlink.go
rename to atproto/atdata/cidlink.go
index c349ec04..3f129622 100644
--- a/atproto/data/cidlink.go
+++ b/atproto/atdata/cidlink.go
@@ -1,4 +1,4 @@
-package data
+package atdata
 
 import (
 	"encoding/json"
diff --git a/atproto/data/const.go b/atproto/atdata/const.go
similarity index 99%
rename from atproto/data/const.go
rename to atproto/atdata/const.go
index a3c28ef0..becd7c98 100644
--- a/atproto/data/const.go
+++ b/atproto/atdata/const.go
@@ -1,4 +1,4 @@
-package data
+package atdata
 
 const (
 	// maximum size of any CBOR data, in any context, in atproto
diff --git a/atproto/data/data.go b/atproto/atdata/data.go
similarity index 99%
rename from atproto/data/data.go
rename to atproto/atdata/data.go
index 560566c2..1d824c4b 100644
--- a/atproto/data/data.go
+++ b/atproto/atdata/data.go
@@ -1,4 +1,4 @@
-package data
+package atdata
 
 import (
 	"encoding/json"
diff --git a/atproto/data/doc.go b/atproto/atdata/doc.go
similarity index 90%
rename from atproto/data/doc.go
rename to atproto/atdata/doc.go
index dd463564..1f78431e 100644
--- a/atproto/data/doc.go
+++ b/atproto/atdata/doc.go
@@ -1,5 +1,5 @@
 /*
-Package data supports schema-less serializaiton and deserialization of atproto data
+Package atdata supports schema-less serializaiton and deserialization of atproto data
 
 Some restrictions from the data model include:
 - string sizes
@@ -15,4 +15,4 @@ Can parse generic atproto records (or other objects) in JSON or CBOR format in t
 
 Has a helper for serializing generic data (map[string]interface{}) to CBOR, which handles converting JSON-style object types (like $link and $bytes) as needed. There is no "MarshalJSON" method; simply use the standard library's `encoding/json`.
 */
-package data
+package atdata
diff --git a/atproto/data/extract.go b/atproto/atdata/extract.go
similarity index 98%
rename from atproto/data/extract.go
rename to atproto/atdata/extract.go
index 81fc6550..b2442a32 100644
--- a/atproto/data/extract.go
+++ b/atproto/atdata/extract.go
@@ -1,4 +1,4 @@
-package data
+package atdata
 
 import (
 	"bytes"
diff --git a/atproto/data/parse.go b/atproto/atdata/parse.go
similarity index 99%
rename from atproto/data/parse.go
rename to atproto/atdata/parse.go
index e8e7412d..23fbd50e 100644
--- a/atproto/data/parse.go
+++ b/atproto/atdata/parse.go
@@ -1,4 +1,4 @@
-package data
+package atdata
 
 import (
 	"encoding"
diff --git a/atproto/auth/jwt.go b/atproto/auth/jwt.go
index 429c82af..c2c99e94 100644
--- a/atproto/auth/jwt.go
+++ b/atproto/auth/jwt.go
@@ -9,7 +9,7 @@ import (
 	"log/slog"
 	"time"
 
-	"github.com/bluesky-social/indigo/atproto/crypto"
+	"github.com/bluesky-social/indigo/atproto/atcrypto"
 	"github.com/bluesky-social/indigo/atproto/identity"
 	"github.com/bluesky-social/indigo/atproto/syntax"
 
@@ -122,7 +122,7 @@ func randomNonce() string {
 	return base64.RawURLEncoding.EncodeToString(buf)
 }
 
-func SignServiceAuth(iss syntax.DID, aud string, ttl time.Duration, lexMethod *syntax.NSID, priv crypto.PrivateKey) (string, error) {
+func SignServiceAuth(iss syntax.DID, aud string, ttl time.Duration, lexMethod *syntax.NSID, priv atcrypto.PrivateKey) (string, error) {
 	claims := serviceAuthClaims{
 		RegisteredClaims: jwt.RegisteredClaims{
 			ExpiresAt: jwt.NewNumericDate(time.Now().Add(ttl)),
@@ -138,11 +138,11 @@ func SignServiceAuth(iss syntax.DID, aud string, ttl time.Duration, lexMethod *s
 
 	var sm *signingMethodAtproto
 
-	// NOTE: could also have a crypto.PrivateKey.Alg() method which returns a string
+	// NOTE: could also have a atcrypto.PrivateKey.Alg() method which returns a string
 	switch priv.(type) {
-	case *crypto.PrivateKeyP256:
+	case *atcrypto.PrivateKeyP256:
 		sm = signingMethodES256
-	case *crypto.PrivateKeyK256:
+	case *atcrypto.PrivateKeyK256:
 		sm = signingMethodES256K
 	default:
 		return "", fmt.Errorf("unknown signing key type: %T", priv)
diff --git a/atproto/auth/jwt_signing.go b/atproto/auth/jwt_signing.go
index d0142d35..d7007d57 100644
--- a/atproto/auth/jwt_signing.go
+++ b/atproto/auth/jwt_signing.go
@@ -3,7 +3,7 @@ package auth
 import (
 	"crypto"
 
-	atcrypto "github.com/bluesky-social/indigo/atproto/crypto"
+	"github.com/bluesky-social/indigo/atproto/atcrypto"
 	"github.com/golang-jwt/jwt/v5"
 )
 
@@ -13,7 +13,7 @@ var (
 	supportedAlgs       []string
 )
 
-// Implementation of jwt.SigningMethod for the `atproto/crypto` types.
+// Implementation of jwt.SigningMethod for the `atproto/atcrypto` types.
 type signingMethodAtproto struct {
 	alg      string
 	hash     crypto.Hash
diff --git a/atproto/auth/oauth/cmd/oauth-web-demo/main.go b/atproto/auth/oauth/cmd/oauth-web-demo/main.go
index 742409f8..bcbc7d6b 100644
--- a/atproto/auth/oauth/cmd/oauth-web-demo/main.go
+++ b/atproto/auth/oauth/cmd/oauth-web-demo/main.go
@@ -12,8 +12,8 @@ import (
 
 	_ "github.com/joho/godotenv/autoload"
 
+	"github.com/bluesky-social/indigo/atproto/atcrypto"
 	"github.com/bluesky-social/indigo/atproto/auth/oauth"
-	"github.com/bluesky-social/indigo/atproto/crypto"
 	"github.com/bluesky-social/indigo/atproto/identity"
 	"github.com/bluesky-social/indigo/atproto/syntax"
 
@@ -101,7 +101,7 @@ func runServer(cctx *cli.Context) error {
 
 	// If a client secret key is provided (as a multibase string), turn this in to a confidential client
 	if cctx.String("client-secret-key") != "" && hostname != "" {
-		priv, err := crypto.ParsePrivateMultibase(cctx.String("client-secret-key"))
+		priv, err := atcrypto.ParsePrivateMultibase(cctx.String("client-secret-key"))
 		if err != nil {
 			return err
 		}
diff --git a/atproto/auth/oauth/jwt_signing.go b/atproto/auth/oauth/jwt_signing.go
index 6c3ffe13..4981189d 100644
--- a/atproto/auth/oauth/jwt_signing.go
+++ b/atproto/auth/oauth/jwt_signing.go
@@ -4,7 +4,7 @@ import (
 	"crypto"
 	"fmt"
 
-	atcrypto "github.com/bluesky-social/indigo/atproto/crypto"
+	"github.com/bluesky-social/indigo/atproto/atcrypto"
 	"github.com/golang-jwt/jwt/v5"
 )
 
@@ -15,7 +15,7 @@ var (
 	supportedAlgs      []string
 )
 
-// Implementation of jwt.SigningMethod for the `atproto/crypto` types.
+// Implementation of jwt.SigningMethod for the `atproto/atcrypto` types.
 type signingMethodAtproto struct {
 	alg      string
 	hash     crypto.Hash
diff --git a/atproto/auth/oauth/oauth.go b/atproto/auth/oauth/oauth.go
index 4c44c784..8d68fd43 100644
--- a/atproto/auth/oauth/oauth.go
+++ b/atproto/auth/oauth/oauth.go
@@ -11,7 +11,7 @@ import (
 	"strings"
 	"time"
 
-	"github.com/bluesky-social/indigo/atproto/crypto"
+	"github.com/bluesky-social/indigo/atproto/atcrypto"
 	"github.com/bluesky-social/indigo/atproto/identity"
 	"github.com/bluesky-social/indigo/atproto/syntax"
 
@@ -43,7 +43,7 @@ type ClientConfig struct {
 	UserAgent string
 
 	// For confidential clients, the private client assertion key. Note that while an interface is used here, only P-256 is allowed by the current specification.
-	PrivateKey crypto.PrivateKey
+	PrivateKey atcrypto.PrivateKey
 
 	// ID for current client assertion key (should be provided if PrivateKey is)
 	KeyID *string
@@ -112,11 +112,11 @@ func (config *ClientConfig) IsConfidential() bool {
 	return config.PrivateKey != nil && config.KeyID != nil
 }
 
-func (config *ClientConfig) SetClientSecret(priv crypto.PrivateKey, keyID string) error {
+func (config *ClientConfig) SetClientSecret(priv atcrypto.PrivateKey, keyID string) error {
 	switch priv.(type) {
-	case *crypto.PrivateKeyP256:
+	case *atcrypto.PrivateKeyP256:
 		// pass
-	case *crypto.PrivateKeyK256:
+	case *atcrypto.PrivateKeyK256:
 		return fmt.Errorf("only P-256 (ES256) private keys supported for atproto OAuth")
 	default:
 		return fmt.Errorf("unknown private key type: %T", priv)
@@ -131,7 +131,7 @@ func (config *ClientConfig) SetClientSecret(priv crypto.PrivateKey, keyID string
 // If the client does not have any keys (eg, public client), returns an empty set.
 func (config *ClientConfig) PublicJWKS() JWKS {
 
-	jwks := JWKS{Keys: []crypto.JWK{}}
+	jwks := JWKS{Keys: []atcrypto.JWK{}}
 
 	// public client with no keys
 	if config.PrivateKey == nil || config.KeyID == nil {
@@ -148,7 +148,7 @@ func (config *ClientConfig) PublicJWKS() JWKS {
 	}
 	jwk.KeyID = config.KeyID
 
-	jwks.Keys = []crypto.JWK{*jwk}
+	jwks.Keys = []atcrypto.JWK{*jwk}
 	return jwks
 }
 
@@ -209,7 +209,7 @@ func (app *ClientApp) ResumeSession(ctx context.Context, did syntax.DID, session
 	}
 
 	// TODO: refactor this in to ClientAuthStore layer?
-	priv, err := crypto.ParsePrivateMultibase(sd.DPoPPrivateKeyMultibase)
+	priv, err := atcrypto.ParsePrivateMultibase(sd.DPoPPrivateKeyMultibase)
 	if err != nil {
 		return nil, err
 	}
@@ -264,7 +264,7 @@ func (cfg *ClientConfig) NewClientAssertion(authURL string) (string, error) {
 // Creates a DPoP token (JWT) for use with an OAuth Auth Server (not to be used with Resource Server). The returned JWT is not bound to an Access Token (no 'ath'), and does not indicate an issuer ('iss').
 //
 // This is used during initial auth request (PAR), initial token request, and subsequent refresh token requests. Note that a full [ClientSession] is not available in several of these circumstances, so this is a stand-alone function.
-func NewAuthDPoP(httpMethod, url, dpopNonce string, privKey crypto.PrivateKey) (string, error) {
+func NewAuthDPoP(httpMethod, url, dpopNonce string, privKey atcrypto.PrivateKey) (string, error) {
 
 	claims := dpopClaims{
 		HTTPMethod: httpMethod,
@@ -356,7 +356,7 @@ func (app *ClientApp) SendAuthRequest(ctx context.Context, authMeta *AuthServerM
 	dpopServerNonce := ""
 
 	// create new key for the session
-	dpopPrivKey, err := crypto.GeneratePrivateKeyP256()
+	dpopPrivKey, err := atcrypto.GeneratePrivateKeyP256()
 	if err != nil {
 		return nil, err
 	}
@@ -447,7 +447,7 @@ func (app *ClientApp) SendInitialTokenRequest(ctx context.Context, authCode stri
 		body.ClientAssertion = &clientAssertion
 	}
 
-	dpopPrivKey, err := crypto.ParsePrivateMultibase(info.DPoPPrivateKeyMultibase)
+	dpopPrivKey, err := atcrypto.ParsePrivateMultibase(info.DPoPPrivateKeyMultibase)
 	if err != nil {
 		return nil, err
 	}
diff --git a/atproto/auth/oauth/session.go b/atproto/auth/oauth/session.go
index 5d89f43f..f78fe0ec 100644
--- a/atproto/auth/oauth/session.go
+++ b/atproto/auth/oauth/session.go
@@ -13,8 +13,8 @@ import (
 	"sync"
 	"time"
 
-	"github.com/bluesky-social/indigo/atproto/client"
-	"github.com/bluesky-social/indigo/atproto/crypto"
+	"github.com/bluesky-social/indigo/atproto/atclient"
+	"github.com/bluesky-social/indigo/atproto/atcrypto"
 	"github.com/bluesky-social/indigo/atproto/syntax"
 
 	"github.com/golang-jwt/jwt/v5"
@@ -64,7 +64,7 @@ type ClientSessionData struct {
 	// TODO: also persist access token creation time / expiration time? In context that token might not be an easily parsed JWT
 }
 
-// Implementation of [client.AuthMethod] for an OAuth session. Handles DPoP request token signing and nonce rotation, and token refresh requests. Optionally uses a callback to persist updated session data.
+// Implementation of [atclient.AuthMethod] for an OAuth session. Handles DPoP request token signing and nonce rotation, and token refresh requests. Optionally uses a callback to persist updated session data.
 //
 // A single ClientSession instance can be called concurrently: updates to session data (the 'Data' field) are protected with a RW mutex lock. Note that concurrent calls to distinct ClientSession instances for the same session could result in clobbered session data.
 type ClientSession struct {
@@ -73,7 +73,7 @@ type ClientSession struct {
 
 	Config         *ClientConfig
 	Data           *ClientSessionData
-	DPoPPrivateKey crypto.PrivateKey
+	DPoPPrivateKey atcrypto.PrivateKey
 
 	PersistSessionCallback PersistSessionCallback
 
@@ -397,9 +397,9 @@ func (sess *ClientSession) DoWithAuth(c *http.Client, req *http.Request, endpoin
 	return nil, fmt.Errorf("OAuth client ran out of request retries")
 }
 
-// Creates a new [client.APIClient] which wraps this session for auth.
-func (sess *ClientSession) APIClient() *client.APIClient {
-	c := client.APIClient{
+// Creates a new [atclient.APIClient] which wraps this session for auth.
+func (sess *ClientSession) APIClient() *atclient.APIClient {
+	c := atclient.APIClient{
 		Client:     sess.Client,
 		Host:       sess.Data.HostURL,
 		Auth:       sess,
diff --git a/atproto/auth/oauth/types.go b/atproto/auth/oauth/types.go
index 87c91344..00df936f 100644
--- a/atproto/auth/oauth/types.go
+++ b/atproto/auth/oauth/types.go
@@ -7,7 +7,7 @@ import (
 	"slices"
 	"strings"
 
-	"github.com/bluesky-social/indigo/atproto/crypto"
+	"github.com/bluesky-social/indigo/atproto/atcrypto"
 	"github.com/bluesky-social/indigo/atproto/syntax"
 )
 
@@ -19,7 +19,7 @@ var (
 )
 
 type JWKS struct {
-	Keys []crypto.JWK `json:"keys"`
+	Keys []atcrypto.JWK `json:"keys"`
 }
 
 // Expected response type from looking up OAuth Protected Resource information on a server (eg, a PDS instance)
diff --git a/atproto/identity/identity.go b/atproto/identity/identity.go
index 5015e183..663c6c0f 100644
--- a/atproto/identity/identity.go
+++ b/atproto/identity/identity.go
@@ -5,7 +5,7 @@ import (
 	"net/url"
 	"strings"
 
-	"github.com/bluesky-social/indigo/atproto/crypto"
+	"github.com/bluesky-social/indigo/atproto/atcrypto"
 	"github.com/bluesky-social/indigo/atproto/syntax"
 
 	"github.com/mr-tron/base58"
@@ -119,8 +119,8 @@ func (ident *Identity) DIDDocument() DIDDocument {
 //
 // Returns [ErrKeyNotFound] if there is no such key.
 //
-// Note that [crypto.PublicKey] is an interface, not a concrete type.
-func (i *Identity) PublicKey() (crypto.PublicKey, error) {
+// Note that [atcrypto.PublicKey] is an interface, not a concrete type.
+func (i *Identity) PublicKey() (atcrypto.PublicKey, error) {
 	return i.GetPublicKey("atproto")
 }
 
@@ -128,8 +128,8 @@ func (i *Identity) PublicKey() (crypto.PublicKey, error) {
 //
 // Returns [ErrKeyNotFound] if there is no such key.
 //
-// Note that [crypto.PublicKey] is an interface, not a concrete type.
-func (i *Identity) GetPublicKey(id string) (crypto.PublicKey, error) {
+// Note that [atcrypto.PublicKey] is an interface, not a concrete type.
+func (i *Identity) GetPublicKey(id string) (atcrypto.PublicKey, error) {
 	if i.Keys == nil {
 		return nil, ErrKeyNotDeclared
 	}
@@ -139,7 +139,7 @@ func (i *Identity) GetPublicKey(id string) (crypto.PublicKey, error) {
 	}
 	switch k.Type {
 	case "Multikey":
-		return crypto.ParsePublicMultibase(k.PublicKeyMultibase)
+		return atcrypto.ParsePublicMultibase(k.PublicKeyMultibase)
 	case "EcdsaSecp256r1VerificationKey2019":
 		if len(k.PublicKeyMultibase) < 2 || k.PublicKeyMultibase[0] != 'z' {
 			return nil, fmt.Errorf("identity key not a multibase base58btc string")
@@ -148,7 +148,7 @@ func (i *Identity) GetPublicKey(id string) (crypto.PublicKey, error) {
 		if err != nil {
 			return nil, fmt.Errorf("identity key multibase parsing: %w", err)
 		}
-		return crypto.ParsePublicUncompressedBytesP256(keyBytes)
+		return atcrypto.ParsePublicUncompressedBytesP256(keyBytes)
 	case "EcdsaSecp256k1VerificationKey2019":
 		if len(k.PublicKeyMultibase) < 2 || k.PublicKeyMultibase[0] != 'z' {
 			return nil, fmt.Errorf("identity key not a multibase base58btc string")
@@ -157,7 +157,7 @@ func (i *Identity) GetPublicKey(id string) (crypto.PublicKey, error) {
 		if err != nil {
 			return nil, fmt.Errorf("identity key multibase parsing: %w", err)
 		}
-		return crypto.ParsePublicUncompressedBytesK256(keyBytes)
+		return atcrypto.ParsePublicUncompressedBytesK256(keyBytes)
 	default:
 		return nil, fmt.Errorf("unsupported atproto public key type: %s", k.Type)
 	}
diff --git a/atproto/label/cbor_gen.go b/atproto/labeling/cbor_gen.go
similarity index 99%
rename from atproto/label/cbor_gen.go
rename to atproto/labeling/cbor_gen.go
index ee964648..8c3b2074 100644
--- a/atproto/label/cbor_gen.go
+++ b/atproto/labeling/cbor_gen.go
@@ -1,6 +1,6 @@
 // Code generated by github.com/whyrusleeping/cbor-gen. DO NOT EDIT.
 
-package label
+package labeling
 
 import (
 	"fmt"
@@ -159,7 +159,7 @@ func (t *Label) MarshalCBOR(w io.Writer) error {
 		}
 	}
 
-	// t.Sig (data.Bytes) (slice)
+	// t.Sig (atdata.Bytes) (slice)
 	if t.Sig != nil {
 
 		if len("sig") > 1000000 {
@@ -408,7 +408,7 @@ func (t *Label) UnmarshalCBOR(r io.Reader) (err error) {
 					t.Negated = &val
 				}
 			}
-			// t.Sig (data.Bytes) (slice)
+			// t.Sig (atdata.Bytes) (slice)
 		case "sig":
 
 			maj, extra, err = cr.ReadHeader()
diff --git a/atproto/label/label.go b/atproto/labeling/label.go
similarity index 79%
rename from atproto/label/label.go
rename to atproto/labeling/label.go
index be48d6a9..5bdd905a 100644
--- a/atproto/label/label.go
+++ b/atproto/labeling/label.go
@@ -1,12 +1,12 @@
-package label
+package labeling
 
 import (
 	"bytes"
 	"fmt"
 
 	comatproto "github.com/bluesky-social/indigo/api/atproto"
-	"github.com/bluesky-social/indigo/atproto/crypto"
-	"github.com/bluesky-social/indigo/atproto/data"
+	"github.com/bluesky-social/indigo/atproto/atcrypto"
+	"github.com/bluesky-social/indigo/atproto/atdata"
 	"github.com/bluesky-social/indigo/atproto/syntax"
 )
 
@@ -14,15 +14,15 @@ import (
 const ATPROTO_LABEL_VERSION int64 = 1
 
 type Label struct {
-	CID       *string    `json:"cid,omitempty" cborgen:"cid,omitempty"`
-	CreatedAt string     `json:"cts" cborgen:"cts"`
-	ExpiresAt *string    `json:"exp,omitempty" cborgen:"exp,omitempty"`
-	Negated   *bool      `json:"neg,omitempty" cborgen:"neg,omitempty"`
-	SourceDID string     `json:"src" cborgen:"src"`
-	URI       string     `json:"uri" cborgen:"uri"`
-	Val       string     `json:"val" cborgen:"val"`
-	Version   int64      `json:"ver" cborgen:"ver"`
-	Sig       data.Bytes `json:"sig,omitempty" cborgen:"sig,omitempty"`
+	CID       *string      `json:"cid,omitempty" cborgen:"cid,omitempty"`
+	CreatedAt string       `json:"cts" cborgen:"cts"`
+	ExpiresAt *string      `json:"exp,omitempty" cborgen:"exp,omitempty"`
+	Negated   *bool        `json:"neg,omitempty" cborgen:"neg,omitempty"`
+	SourceDID string       `json:"src" cborgen:"src"`
+	URI       string       `json:"uri" cborgen:"uri"`
+	Val       string       `json:"val" cborgen:"val"`
+	Version   int64        `json:"ver" cborgen:"ver"`
+	Sig       atdata.Bytes `json:"sig,omitempty" cborgen:"sig,omitempty"`
 }
 
 // converts to map[string]any for printing as JSON
@@ -45,7 +45,7 @@ func (l *Label) Data() map[string]any {
 		d["neg"] = l.Negated
 	}
 	if l.Sig != nil {
-		d["sig"] = data.Bytes(l.Sig)
+		d["sig"] = atdata.Bytes(l.Sig)
 	}
 	return d
 }
@@ -110,7 +110,7 @@ func (l *Label) UnsignedBytes() ([]byte, error) {
 }
 
 // Signs the commit, storing the signature in the `Sig` field
-func (l *Label) Sign(privkey crypto.PrivateKey) error {
+func (l *Label) Sign(privkey atcrypto.PrivateKey) error {
 	b, err := l.UnsignedBytes()
 	if err != nil {
 		return err
@@ -124,7 +124,7 @@ func (l *Label) Sign(privkey crypto.PrivateKey) error {
 }
 
 // Verifies `Sig` field using the provided key. Returns `nil` if signature is valid.
-func (l *Label) VerifySignature(pubkey crypto.PublicKey) error {
+func (l *Label) VerifySignature(pubkey atcrypto.PublicKey) error {
 	if l.Sig == nil {
 		return fmt.Errorf("can not verify unsigned commit")
 	}
diff --git a/atproto/lexicon/cmd/lextool/net.go b/atproto/lexicon/cmd/lextool/net.go
index 92b57dbc..1cd9ad14 100644
--- a/atproto/lexicon/cmd/lextool/net.go
+++ b/atproto/lexicon/cmd/lextool/net.go
@@ -7,7 +7,7 @@ import (
 	"log/slog"
 	"net/http"
 
-	"github.com/bluesky-social/indigo/atproto/data"
+	"github.com/bluesky-social/indigo/atproto/atdata"
 	"github.com/bluesky-social/indigo/atproto/identity"
 	"github.com/bluesky-social/indigo/atproto/lexicon"
 	"github.com/bluesky-social/indigo/atproto/syntax"
@@ -64,7 +64,7 @@ func runValidateRecord(cctx *cli.Context) error {
 		return err
 	}
 
-	body, err := data.UnmarshalJSON(respBytes)
+	body, err := atdata.UnmarshalJSON(respBytes)
 	if err != nil {
 		return err
 	}
diff --git a/atproto/lexicon/language.go b/atproto/lexicon/language.go
index 259382a3..2631daec 100644
--- a/atproto/lexicon/language.go
+++ b/atproto/lexicon/language.go
@@ -6,7 +6,7 @@ import (
 	"reflect"
 	"strings"
 
-	"github.com/bluesky-social/indigo/atproto/data"
+	"github.com/bluesky-social/indigo/atproto/atdata"
 	"github.com/bluesky-social/indigo/atproto/syntax"
 
 	"github.com/rivo/uniseg"
@@ -810,7 +810,7 @@ func (s *SchemaBytes) CheckSchema() error {
 }
 
 func (s *SchemaBytes) Validate(d any) error {
-	v, ok := d.(data.Bytes)
+	v, ok := d.(atdata.Bytes)
 	if !ok {
 		return fmt.Errorf("expecting bytes")
 	}
@@ -830,7 +830,7 @@ func (s *SchemaCIDLink) CheckSchema() error {
 }
 
 func (s *SchemaCIDLink) Validate(d any) error {
-	_, ok := d.(data.CIDLink)
+	_, ok := d.(atdata.CIDLink)
 	if !ok {
 		return fmt.Errorf("expecting a cid-link")
 	}
@@ -915,7 +915,7 @@ func (s *SchemaBlob) CheckSchema() error {
 }
 
 func (s *SchemaBlob) Validate(d any, flags ValidateFlags) error {
-	v, ok := d.(data.Blob)
+	v, ok := d.(atdata.Blob)
 	if !ok {
 		return fmt.Errorf("expected a blob")
 	}
diff --git a/atproto/lexicon/resolve.go b/atproto/lexicon/resolve.go
index c987093f..ed018a74 100644
--- a/atproto/lexicon/resolve.go
+++ b/atproto/lexicon/resolve.go
@@ -7,7 +7,7 @@ import (
 	"log/slog"
 
 	"github.com/bluesky-social/indigo/api/agnostic"
-	"github.com/bluesky-social/indigo/atproto/data"
+	"github.com/bluesky-social/indigo/atproto/atdata"
 	"github.com/bluesky-social/indigo/atproto/identity"
 	"github.com/bluesky-social/indigo/atproto/syntax"
 	"github.com/bluesky-social/indigo/xrpc"
@@ -25,7 +25,7 @@ func ResolveLexiconData(ctx context.Context, dir identity.Directory, nsid syntax
 		return nil, err
 	}
 
-	d, err := data.UnmarshalJSON(*record)
+	d, err := atdata.UnmarshalJSON(*record)
 	if err != nil {
 		return nil, fmt.Errorf("fetched Lexicon schema record was invalid: %w", err)
 	}
diff --git a/atproto/repo/commit.go b/atproto/repo/commit.go
index 37c1481c..aa364f11 100644
--- a/atproto/repo/commit.go
+++ b/atproto/repo/commit.go
@@ -4,8 +4,8 @@ import (
 	"bytes"
 	"fmt"
 
-	"github.com/bluesky-social/indigo/atproto/crypto"
-	"github.com/bluesky-social/indigo/atproto/data"
+	"github.com/bluesky-social/indigo/atproto/atcrypto"
+	"github.com/bluesky-social/indigo/atproto/atdata"
 	"github.com/bluesky-social/indigo/atproto/syntax"
 
 	"github.com/ipfs/go-cid"
@@ -45,11 +45,11 @@ func (c *Commit) AsData() map[string]any {
 	d := map[string]any{
 		"did":     c.DID,
 		"version": c.Version,
-		"prev":    (*data.CIDLink)(c.Prev),
-		"data":    data.CIDLink(c.Data),
+		"prev":    (*atdata.CIDLink)(c.Prev),
+		"data":    atdata.CIDLink(c.Data),
 	}
 	if c.Sig != nil {
-		d["sig"] = data.Bytes(c.Sig)
+		d["sig"] = atdata.Bytes(c.Sig)
 	}
 	if c.Rev != "" {
 		d["rev"] = c.Rev
@@ -80,7 +80,7 @@ func (c *Commit) UnsignedBytes() ([]byte, error) {
 }
 
 // Signs the commit, storing the signature in the `Sig` field
-func (c *Commit) Sign(privkey crypto.PrivateKey) error {
+func (c *Commit) Sign(privkey atcrypto.PrivateKey) error {
 	b, err := c.UnsignedBytes()
 	if err != nil {
 		return err
@@ -94,7 +94,7 @@ func (c *Commit) Sign(privkey crypto.PrivateKey) error {
 }
 
 // Verifies `Sig` field using the provided key. Returns `nil` if signature is valid.
-func (c *Commit) VerifySignature(pubkey crypto.PublicKey) error {
+func (c *Commit) VerifySignature(pubkey atcrypto.PublicKey) error {
 	if c.Sig == nil {
 		return fmt.Errorf("can not verify unsigned commit")
 	}
diff --git a/automod/engine/blobs.go b/automod/engine/blobs.go
index 68ed8267..162086a6 100644
--- a/automod/engine/blobs.go
+++ b/automod/engine/blobs.go
@@ -7,7 +7,7 @@ import (
 	"strings"
 	"time"
 
-	"github.com/bluesky-social/indigo/atproto/data"
+	"github.com/bluesky-social/indigo/atproto/atdata"
 	lexutil "github.com/bluesky-social/indigo/lex/util"
 
 	"github.com/carlmjohnson/versioninfo"
@@ -22,13 +22,13 @@ func (c *RecordContext) Blobs() ([]lexutil.LexBlob, error) {
 		return []lexutil.LexBlob{}, nil
 	}
 
-	rec, err := data.UnmarshalCBOR(c.RecordOp.RecordCBOR)
+	rec, err := atdata.UnmarshalCBOR(c.RecordOp.RecordCBOR)
 	if err != nil {
 		return nil, fmt.Errorf("parsing generic record CBOR: %v", err)
 	}
-	blobs := data.ExtractBlobs(rec)
+	blobs := atdata.ExtractBlobs(rec)
 
-	// convert from data.Blob to lexutil.LexBlob; plan is to merge these types eventually
+	// convert from atdata.Blob to lexutil.LexBlob; plan is to merge these types eventually
 	var out []lexutil.LexBlob
 	for _, b := range blobs {
 		lb := lexutil.LexBlob{
diff --git a/cmd/astrolabe/handlers.go b/cmd/astrolabe/handlers.go
index f5a06726..fdfca1a5 100644
--- a/cmd/astrolabe/handlers.go
+++ b/cmd/astrolabe/handlers.go
@@ -9,7 +9,7 @@ import (
 	"github.com/bluesky-social/indigo/api/agnostic"
 	comatproto "github.com/bluesky-social/indigo/api/atproto"
 	_ "github.com/bluesky-social/indigo/api/bsky"
-	"github.com/bluesky-social/indigo/atproto/data"
+	"github.com/bluesky-social/indigo/atproto/atdata"
 	"github.com/bluesky-social/indigo/atproto/identity"
 	"github.com/bluesky-social/indigo/atproto/syntax"
 	"github.com/bluesky-social/indigo/xrpc"
@@ -231,7 +231,7 @@ func (srv *Server) WebRepoRecord(c echo.Context) error {
 		return fmt.Errorf("empty record in response")
 	}
 
-	record, err := data.UnmarshalJSON(*resp.Value)
+	record, err := atdata.UnmarshalJSON(*resp.Value)
 	if err != nil {
 		return fmt.Errorf("fetched record was invalid data: %w", err)
 	}
diff --git a/cmd/netsync/main.go b/cmd/netsync/main.go
index 98d23a62..ab2bc1f6 100644
--- a/cmd/netsync/main.go
+++ b/cmd/netsync/main.go
@@ -19,7 +19,7 @@ import (
 	"syscall"
 	"time"
 
-	"github.com/bluesky-social/indigo/atproto/data"
+	"github.com/bluesky-social/indigo/atproto/atdata"
 	"github.com/bluesky-social/indigo/repo"
 	"github.com/ipfs/go-cid"
 	_ "github.com/joho/godotenv/autoload"
@@ -573,7 +573,7 @@ func (s *NetsyncState) cloneRepo(ctx context.Context, did string) (cloneState st
 			collectionsSeen[collection] = struct{}{}
 		}
 
-		asCbor, err := data.UnmarshalCBOR(*rec)
+		asCbor, err := atdata.UnmarshalCBOR(*rec)
 		if err != nil {
 			log.Error("Error unmarshalling record", "err", err)
 			return fmt.Errorf("Failed to unmarshal record: %w", err)
diff --git a/gen/main.go b/gen/main.go
index 338a9c10..18ee7c1a 100644
--- a/gen/main.go
+++ b/gen/main.go
@@ -6,8 +6,8 @@ import (
 	atproto "github.com/bluesky-social/indigo/api/atproto"
 	bsky "github.com/bluesky-social/indigo/api/bsky"
 	chat "github.com/bluesky-social/indigo/api/chat"
-	"github.com/bluesky-social/indigo/atproto/data"
-	"github.com/bluesky-social/indigo/atproto/label"
+	"github.com/bluesky-social/indigo/atproto/atdata"
+	"github.com/bluesky-social/indigo/atproto/labeling"
 	atrepo "github.com/bluesky-social/indigo/atproto/repo"
 	atmst "github.com/bluesky-social/indigo/atproto/repo/mst"
 	"github.com/bluesky-social/indigo/events"
@@ -122,7 +122,7 @@ func main() {
 		panic(err)
 	}
 
-	if err := genCfg.WriteMapEncodersToFile("atproto/data/cbor_gen.go", "data", data.GenericRecord{}, data.LegacyBlobSchema{}, data.BlobSchema{}); err != nil {
+	if err := genCfg.WriteMapEncodersToFile("atproto/atdata/cbor_gen.go", "atdata", atdata.GenericRecord{}, atdata.LegacyBlobSchema{}, atdata.BlobSchema{}); err != nil {
 		panic(err)
 	}
 
@@ -134,7 +134,7 @@ func main() {
 		panic(err)
 	}
 
-	if err := genCfg.WriteMapEncodersToFile("atproto/label/cbor_gen.go", "label", label.Label{}); err != nil {
+	if err := genCfg.WriteMapEncodersToFile("atproto/labeling/cbor_gen.go", "labeling", labeling.Label{}); err != nil {
 		panic(err)
 	}
 }



Test patch:
diff --git a/atproto/client/admin_auth_test.go b/atproto/atclient/admin_auth_test.go
similarity index 98%
rename from atproto/client/admin_auth_test.go
rename to atproto/atclient/admin_auth_test.go
index 1434778c..19bb043e 100644
--- a/atproto/client/admin_auth_test.go
+++ b/atproto/atclient/admin_auth_test.go
@@ -1,4 +1,4 @@
-package client
+package atclient
 
 import (
 	"context"
diff --git a/atproto/client/apiclient_test.go b/atproto/atclient/apiclient_test.go
similarity index 97%
rename from atproto/client/apiclient_test.go
rename to atproto/atclient/apiclient_test.go
index 55c568cc..b227f5dc 100644
--- a/atproto/client/apiclient_test.go
+++ b/atproto/atclient/apiclient_test.go
@@ -1,4 +1,4 @@
-package client
+package atclient
 
 import (
 	"testing"
diff --git a/atproto/client/examples_test.go b/atproto/atclient/examples_test.go
similarity index 96%
rename from atproto/client/examples_test.go
rename to atproto/atclient/examples_test.go
index abf746d3..4d623dcf 100644
--- a/atproto/client/examples_test.go
+++ b/atproto/atclient/examples_test.go
@@ -1,4 +1,4 @@
-package client
+package atclient
 
 import (
 	"context"
diff --git a/atproto/client/params_test.go b/atproto/atclient/params_test.go
similarity index 98%
rename from atproto/client/params_test.go
rename to atproto/atclient/params_test.go
index 55690a34..5db429b5 100644
--- a/atproto/client/params_test.go
+++ b/atproto/atclient/params_test.go
@@ -1,4 +1,4 @@
-package client
+package atclient
 
 import (
 	"net/url"
diff --git a/atproto/client/password_auth_test.go b/atproto/atclient/password_auth_test.go
similarity index 99%
rename from atproto/client/password_auth_test.go
rename to atproto/atclient/password_auth_test.go
index a45f9bfb..6f801207 100644
--- a/atproto/client/password_auth_test.go
+++ b/atproto/atclient/password_auth_test.go
@@ -1,4 +1,4 @@
-package client
+package atclient
 
 import (
 	"bytes"
diff --git a/atproto/client/testdata/body.json b/atproto/atclient/testdata/body.json
similarity index 100%
rename from atproto/client/testdata/body.json
rename to atproto/atclient/testdata/body.json
diff --git a/atproto/crypto/examples_test.go b/atproto/atcrypto/examples_test.go
similarity index 98%
rename from atproto/crypto/examples_test.go
rename to atproto/atcrypto/examples_test.go
index 12d391b8..088626b7 100644
--- a/atproto/crypto/examples_test.go
+++ b/atproto/atcrypto/examples_test.go
@@ -1,4 +1,4 @@
-package crypto
+package atcrypto
 
 import (
 	"encoding/base64"
diff --git a/atproto/crypto/interop_fixtures_test.go b/atproto/atcrypto/interop_fixtures_test.go
similarity index 99%
rename from atproto/crypto/interop_fixtures_test.go
rename to atproto/atcrypto/interop_fixtures_test.go
index 73417c64..7c91b168 100644
--- a/atproto/crypto/interop_fixtures_test.go
+++ b/atproto/atcrypto/interop_fixtures_test.go
@@ -1,4 +1,4 @@
-package crypto
+package atcrypto
 
 import (
 	"encoding/base64"
diff --git a/atproto/crypto/jwk_test.go b/atproto/atcrypto/jwk_test.go
similarity index 99%
rename from atproto/crypto/jwk_test.go
rename to atproto/atcrypto/jwk_test.go
index 23a219de..12c4957f 100644
--- a/atproto/crypto/jwk_test.go
+++ b/atproto/atcrypto/jwk_test.go
@@ -1,4 +1,4 @@
-package crypto
+package atcrypto
 
 import (
 	"testing"
diff --git a/atproto/crypto/keys_test.go b/atproto/atcrypto/keys_test.go
similarity index 99%
rename from atproto/crypto/keys_test.go
rename to atproto/atcrypto/keys_test.go
index c873b64c..80909041 100644
--- a/atproto/crypto/keys_test.go
+++ b/atproto/atcrypto/keys_test.go
@@ -1,4 +1,4 @@
-package crypto
+package atcrypto
 
 import (
 	"crypto/rand"
diff --git a/atproto/crypto/testdata/signature-fixtures.json b/atproto/atcrypto/testdata/signature-fixtures.json
similarity index 100%
rename from atproto/crypto/testdata/signature-fixtures.json
rename to atproto/atcrypto/testdata/signature-fixtures.json
diff --git a/atproto/crypto/testdata/w3c_didkey_K256.json b/atproto/atcrypto/testdata/w3c_didkey_K256.json
similarity index 100%
rename from atproto/crypto/testdata/w3c_didkey_K256.json
rename to atproto/atcrypto/testdata/w3c_didkey_K256.json
diff --git a/atproto/crypto/testdata/w3c_didkey_P256.json b/atproto/atcrypto/testdata/w3c_didkey_P256.json
similarity index 100%
rename from atproto/crypto/testdata/w3c_didkey_P256.json
rename to atproto/atcrypto/testdata/w3c_didkey_P256.json
diff --git a/atproto/crypto/w3c_didkey_test.go b/atproto/atcrypto/w3c_didkey_test.go
similarity index 99%
rename from atproto/crypto/w3c_didkey_test.go
rename to atproto/atcrypto/w3c_didkey_test.go
index 38eb7f45..951e0b20 100644
--- a/atproto/crypto/w3c_didkey_test.go
+++ b/atproto/atcrypto/w3c_didkey_test.go
@@ -1,4 +1,4 @@
-package crypto
+package atcrypto
 
 import (
 	"encoding/hex"
diff --git a/atproto/data/basic_test.go b/atproto/atdata/basic_test.go
similarity index 99%
rename from atproto/data/basic_test.go
rename to atproto/atdata/basic_test.go
index 5d5356c6..bae3d88f 100644
--- a/atproto/data/basic_test.go
+++ b/atproto/atdata/basic_test.go
@@ -1,4 +1,4 @@
-package data
+package atdata
 
 import (
 	"encoding/json"
diff --git a/atproto/data/extract_test.go b/atproto/atdata/extract_test.go
similarity index 97%
rename from atproto/data/extract_test.go
rename to atproto/atdata/extract_test.go
index 3a80892c..e56f15fa 100644
--- a/atproto/data/extract_test.go
+++ b/atproto/atdata/extract_test.go
@@ -1,4 +1,4 @@
-package data
+package atdata
 
 import (
 	"io"
diff --git a/atproto/data/interop_test.go b/atproto/atdata/interop_test.go
similarity index 99%
rename from atproto/data/interop_test.go
rename to atproto/atdata/interop_test.go
index a73da1fb..3955014b 100644
--- a/atproto/data/interop_test.go
+++ b/atproto/atdata/interop_test.go
@@ -1,4 +1,4 @@
-package data
+package atdata
 
 import (
 	"encoding/base64"
diff --git a/atproto/data/testdata/data-model-fixtures.json b/atproto/atdata/testdata/data-model-fixtures.json
similarity index 100%
rename from atproto/data/testdata/data-model-fixtures.json
rename to atproto/atdata/testdata/data-model-fixtures.json
diff --git a/atproto/data/testdata/data-model-invalid.json b/atproto/atdata/testdata/data-model-invalid.json
similarity index 100%
rename from atproto/data/testdata/data-model-invalid.json
rename to atproto/atdata/testdata/data-model-invalid.json
diff --git a/atproto/data/testdata/data-model-valid.json b/atproto/atdata/testdata/data-model-valid.json
similarity index 100%
rename from atproto/data/testdata/data-model-valid.json
rename to atproto/atdata/testdata/data-model-valid.json
diff --git a/atproto/data/testdata/feedpost_record.cbor b/atproto/atdata/testdata/feedpost_record.cbor
similarity index 100%
rename from atproto/data/testdata/feedpost_record.cbor
rename to atproto/atdata/testdata/feedpost_record.cbor
diff --git a/atproto/auth/http_test.go b/atproto/auth/http_test.go
index 8fa119bf..85d36de0 100644
--- a/atproto/auth/http_test.go
+++ b/atproto/auth/http_test.go
@@ -6,7 +6,7 @@ import (
 	"testing"
 	"time"
 
-	"github.com/bluesky-social/indigo/atproto/crypto"
+	"github.com/bluesky-social/indigo/atproto/atcrypto"
 	"github.com/bluesky-social/indigo/atproto/identity"
 	"github.com/bluesky-social/indigo/atproto/syntax"
 
@@ -78,7 +78,7 @@ func TestServiceAuthMiddleware(t *testing.T) {
 	aud := "did:example:aud#svc"
 	lxm := syntax.NSID("com.example.api")
 
-	priv, err := crypto.GeneratePrivateKeyP256()
+	priv, err := atcrypto.GeneratePrivateKeyP256()
 	require.NoError(err)
 	pub, err := priv.PublicKey()
 	require.NoError(err)
diff --git a/atproto/auth/jwt_test.go b/atproto/auth/jwt_test.go
index 371245fb..da4ec7f2 100644
--- a/atproto/auth/jwt_test.go
+++ b/atproto/auth/jwt_test.go
@@ -6,7 +6,7 @@ import (
 	"testing"
 	"time"
 
-	"github.com/bluesky-social/indigo/atproto/crypto"
+	"github.com/bluesky-social/indigo/atproto/atcrypto"
 	"github.com/bluesky-social/indigo/atproto/identity"
 	"github.com/bluesky-social/indigo/atproto/syntax"
 
@@ -19,7 +19,7 @@ func testTime() time.Time {
 	return time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)
 }
 
-func validateMinimal(token string, iss, aud string, pub crypto.PublicKey) error {
+func validateMinimal(token string, iss, aud string, pub atcrypto.PublicKey) error {
 
 	p := jwt.NewParser(
 		jwt.WithValidMethods(supportedAlgs),
@@ -71,7 +71,7 @@ func TestSignatureMethods(t *testing.T) {
 
 	for _, fix := range jwtTestFixtures {
 
-		pubk, err := crypto.ParsePublicDIDKey(fix.pubkey)
+		pubk, err := atcrypto.ParsePublicDIDKey(fix.pubkey)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -80,7 +80,7 @@ func TestSignatureMethods(t *testing.T) {
 	}
 }
 
-func testSigningValidation(t *testing.T, priv crypto.PrivateKey) {
+func testSigningValidation(t *testing.T, priv atcrypto.PrivateKey) {
 	assert := assert.New(t)
 	ctx := context.Background()
 
@@ -88,7 +88,7 @@ func testSigningValidation(t *testing.T, priv crypto.PrivateKey) {
 	aud := "did:example:aud#svc"
 	lxm := syntax.NSID("com.example.api")
 
-	priv, err := crypto.GeneratePrivateKeyP256()
+	priv, err := atcrypto.GeneratePrivateKeyP256()
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -140,7 +140,7 @@ func testSigningValidation(t *testing.T, priv crypto.PrivateKey) {
 }
 
 func TestP256SigningValidation(t *testing.T) {
-	priv, err := crypto.GeneratePrivateKeyP256()
+	priv, err := atcrypto.GeneratePrivateKeyP256()
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -148,7 +148,7 @@ func TestP256SigningValidation(t *testing.T) {
 }
 
 func TestK256SigningValidation(t *testing.T) {
-	priv, err := crypto.GeneratePrivateKeyK256()
+	priv, err := atcrypto.GeneratePrivateKeyK256()
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/atproto/label/label_test.go b/atproto/labeling/label_test.go
similarity index 95%
rename from atproto/label/label_test.go
rename to atproto/labeling/label_test.go
index 0b52ea1d..d90e6924 100644
--- a/atproto/label/label_test.go
+++ b/atproto/labeling/label_test.go
@@ -1,11 +1,11 @@
-package label
+package labeling
 
 import (
 	"encoding/json"
 	"testing"
 
 	comatproto "github.com/bluesky-social/indigo/api/atproto"
-	"github.com/bluesky-social/indigo/atproto/crypto"
+	"github.com/bluesky-social/indigo/atproto/atcrypto"
 
 	"github.com/stretchr/testify/assert"
 )
@@ -14,7 +14,7 @@ func TestVerifyLabel(t *testing.T) {
 	assert := assert.New(t)
 
 	pubkeyStr := "zQ3shcnfWLQN1bY4d2patsEAYFzy4xp1zdckEvHsV7S4ocTnC"
-	pubkey, err := crypto.ParsePublicMultibase(pubkeyStr)
+	pubkey, err := atcrypto.ParsePublicMultibase(pubkeyStr)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -77,7 +77,7 @@ func TestSignLabel(t *testing.T) {
 		SourceDID: "did:plc:ewvi7nxzyoun6zhxrhs64oiz",
 	}
 
-	priv, err := crypto.GeneratePrivateKeyK256()
+	priv, err := atcrypto.GeneratePrivateKeyK256()
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/atproto/lexicon/examples_test.go b/atproto/lexicon/examples_test.go
index fe2cd056..150700ff 100644
--- a/atproto/lexicon/examples_test.go
+++ b/atproto/lexicon/examples_test.go
@@ -3,7 +3,7 @@ package lexicon
 import (
 	"fmt"
 
-	atdata "github.com/bluesky-social/indigo/atproto/data"
+	"github.com/bluesky-social/indigo/atproto/atdata"
 )
 
 func ExampleValidateRecord() {
@@ -14,7 +14,7 @@ func ExampleValidateRecord() {
 		panic("failed to load lexicons")
 	}
 
-	// Parse record JSON data using atproto/data helper
+	// Parse record JSON data using atdata helper
 	recordJSON := `{
 		"$type": "example.lexicon.record",
 		"integer": 123,
diff --git a/atproto/lexicon/interop_record_test.go b/atproto/lexicon/interop_record_test.go
index cb654699..bfe1611e 100644
--- a/atproto/lexicon/interop_record_test.go
+++ b/atproto/lexicon/interop_record_test.go
@@ -7,7 +7,7 @@ import (
 	"os"
 	"testing"
 
-	"github.com/bluesky-social/indigo/atproto/data"
+	"github.com/bluesky-social/indigo/atproto/atdata"
 
 	"github.com/stretchr/testify/assert"
 )
@@ -44,7 +44,7 @@ func TestInteropRecordValid(t *testing.T) {
 
 	for _, fixture := range fixtures {
 		fmt.Println(fixture.Name)
-		d, err := data.UnmarshalJSON(fixture.Data)
+		d, err := atdata.UnmarshalJSON(fixture.Data)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -79,7 +79,7 @@ func TestInteropRecordInvalid(t *testing.T) {
 
 	for _, fixture := range fixtures {
 		fmt.Println(fixture.Name)
-		d, err := data.UnmarshalJSON(fixture.Data)
+		d, err := atdata.UnmarshalJSON(fixture.Data)
 		if err != nil {
 			t.Fatal(err)
 		}