Skip to content

Commit 0ec2006

Browse files
committed
refactor: flatten signatures array directly onto records
Replace the signatureData wrapper object with a direct signatures property on all record lexicons. app.certified.signature.list is now a reusable array type (not an object), so records have flat access at record.signatures[] instead of record.signatureData.signatures[]. This matches the ATProtocol Attestation Specification structure and eliminates unnecessary nesting while keeping the array definition DRY via a single shared lexicon ref.
1 parent 4a2dafa commit 0ec2006

25 files changed

Lines changed: 60 additions & 92 deletions

.changeset/fuzzy-pandas-smile.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ Adds optional cryptographic signature support to all record lexicons, enabling p
99
**New lexicons:**
1010

1111
- `app.certified.signature.inline` - Inline cryptographic signature object with JOSE algorithm identifiers (ES256, ES256K, Ed25519)
12-
- `app.certified.signature.list` - Container object with `signatures` array supporting both inline signatures and remote attestation references
12+
- `app.certified.signature.list` - Reusable array type (union of inline signatures and strongRefs to remote proofs)
1313
- `app.certified.signature.proof` - Remote attestation proof record containing the CID of attested content
1414

1515
**Changes to existing lexicons:**
1616

17-
All 20 record lexicons now include an optional `signatureData` property that references `app.certified.signature.list`:
17+
All 20 record lexicons now include an optional `signatures` property (a ref to `app.certified.signature.list`) placed directly on the record with no wrapper object:
1818

1919
- `org.hypercerts.claim.activity`
2020
- `org.hypercerts.claim.contribution`

ERD.puml

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -238,13 +238,6 @@ dataclass signatureInline {
238238
!endif
239239
}
240240

241-
' app.certified.signature.list
242-
dataclass signatureList {
243-
!if (SHOW_FIELDS == "true")
244-
signatures[]?
245-
!endif
246-
}
247-
248241
' app.certified.signature.proof
249242
dataclass signatureProof {
250243
!if (SHOW_FIELDS == "true")
@@ -426,26 +419,12 @@ badgeAward::subject --> activity
426419
'badgeAward::subject --[norank]-> collection
427420

428421
' Signature relationships
429-
signatureList::signatures --> signatureInline
430-
signatureList::signatures --> signatureProof : "strongRef"
431-
432-
' signatureData relationships (all record lexicons reference signatureList)
433-
activity ..> signatureList : signatureData
434-
collection ..> signatureList : signatureData
435-
attachment ..> signatureList : signatureData
436-
measurement ..> signatureList : signatureData
437-
evaluation ..> signatureList : signatureData
438-
acknowledgement ..> signatureList : signatureData
439-
contribution ..> signatureList : signatureData
440-
contributorInformation ..> signatureList : signatureData
441-
rights ..> signatureList : signatureData
442-
fundingReceipt ..> signatureList : signatureData
443-
workScopeTag ..> signatureList : signatureData
444-
location ..> signatureList : signatureData
445-
badgeDefinition ..> signatureList : signatureData
446-
badgeAward ..> signatureList : signatureData
447-
badgeResponse ..> signatureList : signatureData
448-
organization ..> signatureList : signatureData
449-
linkEvm ..> signatureList : signatureData
422+
' All record lexicons have an optional `signatures` array (ref to
423+
' app.certified.signature.list) containing a union of signatureInline
424+
' objects and strongRefs to signatureProof records. Only activity is
425+
' shown here to avoid cluttering the diagram; the pattern is identical
426+
' for all record lexicons.
427+
activity ..> signatureInline : signatures
428+
activity ..> signatureProof : "signatures (strongRef)"
450429

451430
@enduml

README.md

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ CERTIFIED ─ shared lexicons (certified.app)
4545
actor/organization (org metadata)
4646
badge/definition ──► badge/award ──► badge/response
4747
signature/inline (embedded cryptographic signature)
48-
signature/list (container for signatures array)
48+
signature/list (reusable signatures array type)
4949
signature/proof (remote attestation proof record)
5050
```
5151

@@ -283,10 +283,10 @@ await agent.api.com.atproto.repo.createRecord({
283283
| Lexicon | NSID | Description |
284284
| -------------------- | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
285285
| **Inline Signature** | `app.certified.signature.inline` | An inline cryptographic signature for attesting to record content. Uses JOSE algorithm identifiers (ES256, ES256K, Ed25519). |
286-
| **Signature List** | `app.certified.signature.list` | Container object with a `signatures` array. Referenced by all record lexicons via `signatureData` property. |
286+
| **Signature List** | `app.certified.signature.list` | Reusable array type (union of inline signatures and strongRefs). Referenced by all record lexicons via the `signatures` property. |
287287
| **Proof** | `app.certified.signature.proof` | Remote attestation proof record containing the CID of attested content. Lives in the attestor's repository and can be referenced via strongRef. |
288288

289-
All record lexicons include an optional `signatureData` property that references `app.certified.signature.list`, enabling cryptographic attestations. See [Cryptographic Signatures](#cryptographic-signatures) for usage details.
289+
All record lexicons include an optional `signatures` property (a ref to `app.certified.signature.list`) enabling cryptographic attestations. See [Cryptographic Signatures](#cryptographic-signatures) for usage details.
290290

291291
> **Full property tables**[SCHEMAS.md](SCHEMAS.md)
292292
@@ -509,7 +509,7 @@ const attachment = {
509509

510510
### Cryptographic Signatures
511511

512-
All record lexicons support optional cryptographic signatures via the `signatureData` property. This enables platform attestation and verification that records were created through trusted services.
512+
All record lexicons support optional cryptographic signatures via the `signatures` property. This enables platform attestation and verification that records were created through trusted services.
513513

514514
Signatures support two patterns:
515515

@@ -525,25 +525,23 @@ const signedActivity = {
525525
title: "Verified Reforestation Project",
526526
shortDescription: "Planted 1,000 trees in partnership with local community",
527527
createdAt: new Date().toISOString(),
528-
signatureData: {
529-
signatures: [
530-
// Inline signature (embedded)
531-
{
532-
$type: "app.certified.signature.inline",
533-
signatureType: "ES256K", // JOSE algorithm: secp256k1
534-
signature: new Uint8Array([
535-
/* signature bytes */
536-
]),
537-
key: "did:plc:platform123#signing", // DID verification method
538-
},
539-
// Remote attestation (reference to proof in another repo)
540-
{
541-
$type: "com.atproto.repo.strongRef",
542-
uri: "at://did:plc:verifier/app.certified.signature.proof/abc123",
543-
cid: "bafy...",
544-
},
545-
],
546-
},
528+
signatures: [
529+
// Inline signature (embedded)
530+
{
531+
$type: "app.certified.signature.inline",
532+
signatureType: "ES256K", // JOSE algorithm: secp256k1
533+
signature: new Uint8Array([
534+
/* signature bytes */
535+
]),
536+
key: "did:plc:platform123#signing", // DID verification method
537+
},
538+
// Remote attestation (reference to proof in another repo)
539+
{
540+
$type: "com.atproto.repo.strongRef",
541+
uri: "at://did:plc:verifier/app.certified.signature.proof/abc123",
542+
cid: "bafy...",
543+
},
544+
],
547545
};
548546
```
549547

lexicons/app/certified/actor/organization.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
"format": "datetime",
4444
"description": "Client-declared timestamp when this record was originally created."
4545
},
46-
"signatureData": {
46+
"signatures": {
4747
"type": "ref",
4848
"ref": "app.certified.signature.list",
4949
"description": "Optional cryptographic signatures attesting to this record's content."

lexicons/app/certified/actor/profile.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
"format": "datetime",
5555
"description": "Client-declared timestamp when this record was originally created"
5656
},
57-
"signatureData": {
57+
"signatures": {
5858
"type": "ref",
5959
"ref": "app.certified.signature.list",
6060
"description": "Optional cryptographic signatures attesting to this record's content."

lexicons/app/certified/badge/award.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
"format": "datetime",
3737
"description": "Client-declared timestamp when this record was originally created"
3838
},
39-
"signatureData": {
39+
"signatures": {
4040
"type": "ref",
4141
"ref": "app.certified.signature.list",
4242
"description": "Optional cryptographic signatures attesting to this record's content."

lexicons/app/certified/badge/definition.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
"format": "datetime",
6060
"description": "Client-declared timestamp when this record was originally created"
6161
},
62-
"signatureData": {
62+
"signatures": {
6363
"type": "ref",
6464
"ref": "app.certified.signature.list",
6565
"description": "Optional cryptographic signatures attesting to this record's content."

lexicons/app/certified/badge/response.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"format": "datetime",
3131
"description": "Client-declared timestamp when this record was originally created"
3232
},
33-
"signatureData": {
33+
"signatures": {
3434
"type": "ref",
3535
"ref": "app.certified.signature.list",
3636
"description": "Optional cryptographic signatures attesting to this record's content."

lexicons/app/certified/link/evm.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"format": "datetime",
2727
"description": "Client-declared timestamp when this record was originally created."
2828
},
29-
"signatureData": {
29+
"signatures": {
3030
"type": "ref",
3131
"ref": "app.certified.signature.list",
3232
"description": "Optional cryptographic signatures attesting to this record's content."

lexicons/app/certified/location.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
"format": "datetime",
6969
"description": "Client-declared timestamp when this record was originally created"
7070
},
71-
"signatureData": {
71+
"signatures": {
7272
"type": "ref",
7373
"ref": "app.certified.signature.list",
7474
"description": "Optional cryptographic signatures attesting to this record's content."

0 commit comments

Comments
 (0)