diff --git a/.spellcheckerdict.txt b/.spellcheckerdict.txt
index 37868cb5..ec34aeab 100644
--- a/.spellcheckerdict.txt
+++ b/.spellcheckerdict.txt
@@ -8,6 +8,7 @@ CalVer
CC0
Changelog
changeType
+(cid|CID)s?
[Cc]odec('s)?
contentHash
cryptographic
@@ -16,10 +17,11 @@ CtxSharedSecretA
CtxSharedSecretB
CtxSharedSecretBob
Curve25519
-decrypt
+decrypt(ed)?
Delegator
Deserialize
Diffie-Hellman
+discoverability
[Dd]iscoverable
DSNP
DSNP-compatible
@@ -27,6 +29,7 @@ DSNP-referenced
ECIES
EdDSA
[Ee]num(s)?
+encodings
Ethereum
Extrinsics
fromId
@@ -43,6 +46,7 @@ JSON-LD
keccak-256
keyId
keyType
+Kubo
LibertyDSNP
libsodium
little-endian
@@ -68,6 +72,7 @@ Polkadot
Poly1305
pre-configured
PRId([ABs])?
+ProfileResource
[Pp]ublicKey
repo
RFC[1-9][0-9]*
diff --git a/pages/DSNP/Announcements.md b/pages/DSNP/Announcements.md
index 3d025149..8ba5fb8c 100644
--- a/pages/DSNP/Announcements.md
+++ b/pages/DSNP/Announcements.md
@@ -15,7 +15,7 @@ Each Announcement has an enumerated type for use when separating out a stream of
| 2 | [Broadcast](Types/Broadcast.md) | a public post | YES | YES |
| 3 | [Reply](Types/Reply.md) | a public response to a Broadcast | YES | YES |
| 4 | [Reaction](Types/Reaction.md) | a public visual reply to a Broadcast | no | no |
-| 5 | [Profile](Types/Profile.md) | a profile | YES | no |
+| 5 | ~~[Profile](Types/Profile.md)~~c | ~~a profile~~ | ~~YES~~ | ~~no~~ |
| 6 | [Update](Types/Update.md) | an update to content| YES | no |
| 7 | ~~[Public Key](Types/PublicKey.md)~~b | ~~a public key for secure communication~~ | ~~no~~ | ~~no~~ |
@@ -23,6 +23,8 @@ Each Announcement has an enumerated type for use when separating out a stream of
b Since DSNP version 1.3, public keys use [User Data](UserData.md) operations.
+c Since DSNP version 1.3, profile changes use [User Data](UserData.md) operations.
+
## Announcement Validation
There is no guarantee that, at time of creation, a given Announcement will be from the `fromId` claimed in the Announcement.
diff --git a/pages/DSNP/Identifiers.md b/pages/DSNP/Identifiers.md
index ee97f01b..2020e237 100644
--- a/pages/DSNP/Identifiers.md
+++ b/pages/DSNP/Identifiers.md
@@ -49,11 +49,29 @@ Any [Announcement Types](Announcements.md#announcement-types) with a `fromId` an
### Example
```
-dsnp://78187493520/0x1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef
+dsnp://78187493520/QmQNHNfHnbgJJ6nK4UPx2VtTUCafAKCbqZJ6ZRYUGjoeFj
```
| part | value |
| ---- | ----- |
| Scheme | `dsnp://` |
| User Id | `78187493520` |
-| Content Hash | `0x1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef` |
+| Content Hash | `QmQNHNfHnbgJJ6nK4UPx2VtTUCafAKCbqZJ6ZRYUGjoeFj` |
+
+## DSNP CID
+
+A DSNP CID is a valid [Content IDentifier](https://github.com/multiformats/cid) generated using the following parameters.
+
+### Supported CID Parameters
+
+The CID specification allows CIDs to be generated with a wide and ever-growing range of possible hashing algorithms, string encodings, and block sizes.
+In order for DSNP applications to interoperate, the required functionality is limited as follows:
+
+- CID version: MUST be version 1, in order to distinguish CIDs from simple multihash values in situations where either may be used
+- Hash algorithm: MUST be `sha2-256` or `blake2b-256`
+- Encoding: MUST be `base58btc` or `base32`
+- Codec: MUST be `dag-pb` for data 256*1024 bytes or longer; `raw` for data less than 256*1024 bytes
+- Chunking: Non-leaf nodes MUST be 256*1024 bytes
+
+The rationale for these options is to allow consuming applications to attempt to generate a matching CID from a byte stream for validation purposes without the need to reprocess the stream.
+These options are intentionally aligned to interoperate with the default output of the [Kubo](https://github.com/ipfs/kubo) IPFS command line utility when invoked as `ipfs add --cid-version=1 ...`.
diff --git a/pages/DSNP/Identity.md b/pages/DSNP/Identity.md
index 929cd347..99de4eba 100644
--- a/pages/DSNP/Identity.md
+++ b/pages/DSNP/Identity.md
@@ -29,18 +29,29 @@ An implementation MUST NOT allow the user to remove the only or last remaining c
A user may choose to retire their Identifier at any time.
Once an Identifier is retired, an implementation MAY remove all state data associated with that Identifier, provided that an indication that the Identifier is retired remains, so it may not be reused in the future.
-This means that all data previously sent from the Identifier, the keys associated with the Identifier, and the delegations (see next section) associated with the Identifier may be removed.
+This means that all data previously sent from the Identifier, the keys associated with the Identifier, any user data (see below) associated with the Identifier, and the delegations (see next section) associated with the Identifier may be removed.
After an Identifier is retired, any existing or future [Announcements](Announcements.md) from the Identifier should be treated as if they have been [tombstoned](Types/Tombstone.md) (for Announcement Types that support tombstoning).
A retired Identifier MUST NOT be allowed to act as a principal for any additional DSNP [Operations](Operations.md).
-### Delegation
+## Delegation
-* An owner MUST be able to delegate permission to announce on their behalf to other parties.
+* A user MUST be able to delegate and revoke permissions to other parties to submit each type of announcement or replace each type of user data on their behalf.
* A user MUST be able to revoke delegated permissions.
-* Announcements from a delegate MUST be able to be verify which delegate made the specific Announcement.
+* Announcements and user data updates from a delegate MUST be able to be verified as to which delegate was responsible for the action.
* Delegation revocation MUST NOT be retroactive.
+## Identity-Linked State Data
+
+DSNP identities can have linked [User Data](UserData.md), which, like the identifier and delegations, forms part of the shared state of the consensus system.
+As consensus system state storage is generally much more expensive than external data storage, shared state storage is only required for data considered critical for maintaining user agency and discoverability with low latency and high availability.
+
+User data is utilized for the following types of identity-linked data:
+* Public keys that can be used to encrypt data that can later be decrypted by the user or used to verify signatures on documents created by the user
+* [Social Graphs](Graph.md), both public and private (encrypted)
+* Links to [Profile documents](../ActivityContent/Types/Profile.md)
+
+
## Related Operations
* [Create Identifier](Operations.md#create-identifier)
@@ -49,6 +60,8 @@ A retired Identifier MUST NOT be allowed to act as a principal for any additiona
* [Revoke Delegation](Operations.md#revoke-delegation)
* [Add Control Key](Operations.md#add-control-key)
* [Remove Control Key](Operations.md#remove-control-key)
+* [Replace User Data](Operations.md#replace-user-data)
+* [Get User Data](Operations.md#get-user-data)
## Non-normative
diff --git a/pages/DSNP/Migrated.md b/pages/DSNP/Migrated.md
index 15129c81..054599a4 100644
--- a/pages/DSNP/Migrated.md
+++ b/pages/DSNP/Migrated.md
@@ -1,3 +1,4 @@
# Migrated Announcements
-* [Graph Change](Types/GraphChange.md)
+* [Graph Change](Types/GraphChange.md)
+* [Profile](Types/Profile.md)
diff --git a/pages/DSNP/Types/ProfileResource.md b/pages/DSNP/Types/ProfileResource.md
new file mode 100644
index 00000000..b8419653
--- /dev/null
+++ b/pages/DSNP/Types/ProfileResource.md
@@ -0,0 +1,56 @@
+# ProfileResource
+
+A profile-linked resource is represented by the ProfileResource object type.
+
+## Serialization
+
+ProfileResource object serialization MUST conform to the following [Avro](https://avro.apache.org) schema:
+
+```
+{
+ "namespace": "org.dsnp",
+ "name": "ProfileResource",
+ "type": "record",
+ "doc": "Profile-linked resource",
+ "fields": [
+ {
+ "name": "type",
+ "type": "int",
+ "doc": "Type of resource"
+ },
+ {
+ "name": "cid",
+ "type": "string",
+ "doc": "Content IDentifier of resource"
+ },
+ {
+ "name": "length",
+ "type": "int",
+ "doc": "Length of document in bytes"
+ }
+ ]
+}
+```
+
+## Generation
+
+### type
+
+- MUST be a supported DSNP profile-linked resource type.
+
+#### Supported Profile-Linked Resource Types
+
+| Value | Description | Specification | Content Type | DSNP Version Added |
+| --- | --- | --- | --- |
+| 1 | Activity Content Profile with DSNP extensions | [DSNP Profile](../../ActivityContent/Types/Profile.md) | `application/json` | 1.3 |
+
+All other document type values are reserved for future expansion.
+
+### cid
+
+- MUST be a valid [DSNP CID](../Identifiers.md#dsnp-cid]
+
+### length
+
+- MUST be a positive integer
+- MUST match the length in bytes of the document
diff --git a/pages/DSNP/UserData.md b/pages/DSNP/UserData.md
index 1ba1f1be..81bef10c 100644
--- a/pages/DSNP/UserData.md
+++ b/pages/DSNP/UserData.md
@@ -21,6 +21,7 @@ DSNP implementations MUST support the following User Data Types:
| `privateConnectionPRIds` | 1.2 | NONE | NONE | [PRId](Types/PRId.md) |
| `keyAgreementPublicKeys` | 1.3 | NONE | NONE | [PublicKey](Types/PublicKeyUserData.md) |
| `assertionMethodPublicKeys` | 1.3 | NONE | NONE | [PublicKey](Types/PublicKeyUserData.md) |
+| `profileResources` | 1.3 | NONE | NONE | [ProfileResource](Types/ProfileResource.md) |
Data for each data type is initially formatted as a stream of Avro objects that should conform to the schema specified.
A DSNP system MAY limit the number of objects allowed for a given user data type; if so, this MUST be documented.
diff --git a/pages/SUMMARY.md b/pages/SUMMARY.md
index c5875281..14a8f282 100644
--- a/pages/SUMMARY.md
+++ b/pages/SUMMARY.md
@@ -9,17 +9,18 @@
- [Graph Edge](DSNP/Types/GraphEdge.md)
- [PRId](DSNP/Types/PRId.md)
- [Public Key](DSNP/Types/PublicKeyUserData.md)
+ - [ProfileResource](DSNP/Types/ProfileResource.md)
- [Batch Publications](DSNP/BatchPublications.md)
- [Announcements](DSNP/Announcements.md)
- [Tombstone](DSNP/Types/Tombstone.md)
- [Broadcast](DSNP/Types/Broadcast.md)
- [Reply](DSNP/Types/Reply.md)
- [Reaction](DSNP/Types/Reaction.md)
- - [Profile](DSNP/Types/Profile.md)
- [Update](DSNP/Types/Update.md)
- [Migrated Announcements](DSNP/Migrated.md)
- [Graph Change](DSNP/Types/GraphChange.md)
- [Public Key](DSNP/Types/PublicKey.md)
+ - [Profile](DSNP/Types/Profile.md)
- [Operations](DSNP/Operations.md)
- [State Change Records](DSNP/Records.md)
- [Serializations](DSNP/Serializations.md)