at.eptss.candidateLedger
Schema Diff
+30 -33
Compatibility Analysis
Breaking Changes Detected
18 breaking changes, 9 non-breaking changes.
Breaking Changes (18)
- RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "at.eptss.candidateLedger:body", src: "at.eptss.candidateLedger:body", tgt: "at.eptss.candidateLedger:body.nominations", kind: "prop", name: Some("nominations") }
- RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "at.eptss.candidateLedger:body", src: "at.eptss.candidateLedger:body", tgt: "at.eptss.candidateLedger:body.playlist", kind: "prop", name: Some("playlist") }
- RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "at.eptss.candidateLedger#nomination", src: "at.eptss.candidateLedger#nomination", tgt: "at.eptss.candidateLedger#nomination.by", kind: "prop", name: Some("by") }
- RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "at.eptss.candidateLedger#nomination", src: "at.eptss.candidateLedger#nomination", tgt: "at.eptss.candidateLedger#nomination.track", kind: "prop", name: Some("track") }
- RequiredEdgeRemoved RequiredEdgeRemoved { vertex_id: "at.eptss.candidateLedger#candidate", src: "at.eptss.candidateLedger#candidate", tgt: "at.eptss.candidateLedger#candidate.title", kind: "prop", name: Some("title") }
- RequiredEdgeRemoved RequiredEdgeRemoved { vertex_id: "at.eptss.candidateLedger#candidate", src: "at.eptss.candidateLedger#candidate", tgt: "at.eptss.candidateLedger#candidate.artist", kind: "prop", name: Some("artist") }
- RequiredEdgeRemoved RequiredEdgeRemoved { vertex_id: "at.eptss.candidateLedger:body", src: "at.eptss.candidateLedger:body", tgt: "at.eptss.candidateLedger:body.candidates", kind: "prop", name: Some("candidates") }
- RemovedVertex RemovedVertex { vertex_id: "at.eptss.candidateLedger#candidate" }
- RemovedVertex RemovedVertex { vertex_id: "at.eptss.candidateLedger#candidate.artist" }
- RemovedVertex RemovedVertex { vertex_id: "at.eptss.candidateLedger#candidate.listenLink" }
- RemovedVertex RemovedVertex { vertex_id: "at.eptss.candidateLedger#candidate.nominatedBy" }
- RemovedVertex RemovedVertex { vertex_id: "at.eptss.candidateLedger#candidate.title" }
- RemovedVertex RemovedVertex { vertex_id: "at.eptss.candidateLedger:body.candidates" }
- RemovedVertex RemovedVertex { vertex_id: "at.eptss.candidateLedger:body.candidates:items" }
- RemovedEdge RemovedEdge { src: "at.eptss.candidateLedger#candidate", tgt: "at.eptss.candidateLedger#candidate.listenLink", kind: "prop", name: Some("listenLink") }
- RemovedEdge RemovedEdge { src: "at.eptss.candidateLedger#candidate", tgt: "at.eptss.candidateLedger#candidate.nominatedBy", kind: "prop", name: Some("nominatedBy") }
- RemovedEdge RemovedEdge { src: "at.eptss.candidateLedger:body.candidates", tgt: "at.eptss.candidateLedger:body.candidates:items", kind: "items", name: None }
- RemovedEdge RemovedEdge { src: "at.eptss.candidateLedger:body.candidates:items", tgt: "at.eptss.candidateLedger#candidate", kind: "ref", name: None }
Non-Breaking Changes (9)
- AddedVertex AddedVertex { vertex_id: "at.eptss.candidateLedger#nomination" }
- AddedVertex AddedVertex { vertex_id: "at.eptss.candidateLedger#nomination.by" }
- AddedVertex AddedVertex { vertex_id: "at.eptss.candidateLedger#nomination.track" }
- AddedVertex AddedVertex { vertex_id: "at.eptss.candidateLedger:body.nominations" }
- AddedVertex AddedVertex { vertex_id: "at.eptss.candidateLedger:body.nominations:items" }
- AddedVertex AddedVertex { vertex_id: "at.eptss.candidateLedger:body.playlist" }
- AddedEdge AddedEdge { src: "at.eptss.candidateLedger:body.nominations", tgt: "at.eptss.candidateLedger:body.nominations:items", kind: "items", name: None }
- AddedEdge AddedEdge { src: "at.eptss.candidateLedger:body.nominations:items", tgt: "at.eptss.candidateLedger#nomination", kind: "ref", name: None }
- AddedEdge AddedEdge { src: "at.eptss.candidateLedger:body.playlist", tgt: "com.atproto.repo.strongRef", kind: "ref", name: None }
Migration Guidance
Removed Elements
RemovedVertex { vertex_id: "at.eptss.candidateLedger#candidate" }RemovedVertex { vertex_id: "at.eptss.candidateLedger#candidate.artist" }RemovedVertex { vertex_id: "at.eptss.candidateLedger#candidate.listenLink" }RemovedVertex { vertex_id: "at.eptss.candidateLedger#candidate.nominatedBy" }RemovedVertex { vertex_id: "at.eptss.candidateLedger#candidate.title" }RemovedVertex { vertex_id: "at.eptss.candidateLedger:body.candidates" }RemovedVertex { vertex_id: "at.eptss.candidateLedger:body.candidates:items" }
Added Elements
AddedVertex { vertex_id: "at.eptss.candidateLedger#nomination" }AddedVertex { vertex_id: "at.eptss.candidateLedger#nomination.by" }AddedVertex { vertex_id: "at.eptss.candidateLedger#nomination.track" }AddedVertex { vertex_id: "at.eptss.candidateLedger:body.nominations" }AddedVertex { vertex_id: "at.eptss.candidateLedger:body.nominations:items" }AddedVertex { vertex_id: "at.eptss.candidateLedger:body.playlist" }
Additional Notes
- Breaking: RequiredEdgeAdded { vertex_id: "at.eptss.candidateLedger#nomination", src: "at.eptss.candidateLedger#nomination", tgt: "at.eptss.candidateLedger#nomination.by", kind: "prop", name: Some("by") }
- Breaking: RequiredEdgeAdded { vertex_id: "at.eptss.candidateLedger#nomination", src: "at.eptss.candidateLedger#nomination", tgt: "at.eptss.candidateLedger#nomination.track", kind: "prop", name: Some("track") }
- Breaking: RequiredEdgeAdded { vertex_id: "at.eptss.candidateLedger:body", src: "at.eptss.candidateLedger:body", tgt: "at.eptss.candidateLedger:body.nominations", kind: "prop", name: Some("nominations") }
- Breaking: RequiredEdgeAdded { vertex_id: "at.eptss.candidateLedger:body", src: "at.eptss.candidateLedger:body", tgt: "at.eptss.candidateLedger:body.playlist", kind: "prop", name: Some("playlist") }
- Breaking: RequiredEdgeRemoved { vertex_id: "at.eptss.candidateLedger:body", src: "at.eptss.candidateLedger:body", tgt: "at.eptss.candidateLedger:body.candidates", kind: "prop", name: Some("candidates") }
- Breaking: RequiredEdgeRemoved { vertex_id: "at.eptss.candidateLedger#candidate", src: "at.eptss.candidateLedger#candidate", tgt: "at.eptss.candidateLedger#candidate.title", kind: "prop", name: Some("title") }
- Breaking: RequiredEdgeRemoved { vertex_id: "at.eptss.candidateLedger#candidate", src: "at.eptss.candidateLedger#candidate", tgt: "at.eptss.candidateLedger#candidate.artist", kind: "prop", name: Some("artist") }
- Breaking: RemovedEdge { src: "at.eptss.candidateLedger#candidate", tgt: "at.eptss.candidateLedger#candidate.listenLink", kind: "prop", name: Some("listenLink") }
- Breaking: RemovedEdge { src: "at.eptss.candidateLedger#candidate", tgt: "at.eptss.candidateLedger#candidate.nominatedBy", kind: "prop", name: Some("nominatedBy") }
- Breaking: RemovedEdge { src: "at.eptss.candidateLedger:body.candidates", tgt: "at.eptss.candidateLedger:body.candidates:items", kind: "items", name: None }
- Breaking: RemovedEdge { src: "at.eptss.candidateLedger:body.candidates:items", tgt: "at.eptss.candidateLedger#candidate", kind: "ref", name: None }
- Non-breaking: AddedEdge { src: "at.eptss.candidateLedger:body.nominations", tgt: "at.eptss.candidateLedger:body.nominations:items", kind: "items", name: None }
- Non-breaking: AddedEdge { src: "at.eptss.candidateLedger:body.nominations:items", tgt: "at.eptss.candidateLedger#nomination", kind: "ref", name: None }
- Non-breaking: AddedEdge { src: "at.eptss.candidateLedger:body.playlist", tgt: "com.atproto.repo.strongRef", kind: "ref", name: None }
1
1
{
2
2
"$type": "com.atproto.lexicon.schema",
3
3
"defs": {
4
-
"candidate": {
5
-
"properties": {
6
-
"artist": {
7
-
"maxGraphemes": 512,
8
-
"maxLength": 5120,
9
-
"type": "string"
10
-
},
11
-
"listenLink": {
12
-
"format": "uri",
13
-
"type": "string"
14
-
},
15
-
"nominatedBy": {
16
-
"description": "DID of the member who nominated this song. Absent for organizer-carried candidates.",
17
-
"format": "did",
18
-
"type": "string"
19
-
},
20
-
"title": {
21
-
"maxGraphemes": 512,
22
-
"maxLength": 5120,
23
-
"type": "string"
24
-
}
25
-
},
26
-
"required": [
27
-
"title",
28
-
"artist"
29
-
],
30
-
"type": "object"
31
-
},
32
4
"main": {
33
-
"description": "The round's ballot sheet: every nominated song, revealed as one atomic record when signups close. Published by the round organizer. nominatedBy links a candidate to its nominator; entries carried over by an organizer omit it. The organizer is responsible for honoring un-naming requests by editing this record in place.",
5
+
"description": "The round's ballot sheet, revealed as one atomic record when signups close. Published by the round organizer. The candidate list itself lives in an at.atjam.playlist of at.eptss.track records — this record pins that playlist by CID and adds only what a playlist must never carry: round attribution and who nominated what. Ballots strong-ref this ledger, so the pin chain runs ballot → ledger → playlist → tracks, and a post-hoc edit anywhere is detectable. Attribution keys on the track's AT-URI, never on its position — a positional array desyncs silently on one reorder. The organizer honors un-naming requests by editing nominations in place.",
34
6
"key": "any",
35
7
"record": {
36
8
"properties": {
37
-
"candidates": {
9
+
"nominations": {
10
+
"description": "Who put what in the hat. Empty when every candidate was organizer-carried. Tracks absent here are carried candidates, unattributed by design.",
38
11
"items": {
39
-
"ref": "#candidate",
12
+
"ref": "#nomination",
40
13
"type": "ref"
41
14
},
42
15
"maxLength": 256,
43
-
"minLength": 1,
44
16
"type": "array"
45
17
},
18
+
"playlist": {
19
+
"description": "The at.atjam.playlist holding the candidates, in ballot order, CID-pinned.",
20
+
"ref": "com.atproto.repo.strongRef",
21
+
"type": "ref"
22
+
},
46
23
"publishedAt": {
47
24
"format": "datetime",
48
25
"type": "string"
49
26
},
50
27
"round": {
51
28
"description": "The at.atjam.round this ledger belongs to.",
52
29
"ref": "com.atproto.repo.strongRef",
53
30
"type": "ref"
54
31
}
55
32
},
56
33
"required": [
57
34
"round",
58
-
"candidates",
35
+
"playlist",
36
+
"nominations",
59
37
"publishedAt"
60
38
],
61
39
"type": "object"
62
40
},
63
41
"type": "record"
42
+
},
43
+
"nomination": {
44
+
"properties": {
45
+
"by": {
46
+
"description": "DID of the member who nominated it.",
47
+
"format": "did",
48
+
"type": "string"
49
+
},
50
+
"track": {
51
+
"description": "The at.eptss.track this attribution is about. A URI and not an index: identity, not position.",
52
+
"format": "at-uri",
53
+
"type": "string"
54
+
}
55
+
},
56
+
"required": [
57
+
"track",
58
+
"by"
59
+
],
60
+
"type": "object"
64
61
}
65
62
},
66
63
"id": "at.eptss.candidateLedger",
67
64
"lexicon": 1
68
65
}