at.eptss.candidateLedger

eptss.at

Schema Diff

+30 -33

From

CID
bafyreiho7e3g6df...
Indexed At
2026-08-01 05:41 UTC
View this version

To

CID
bafyreidjztfzp6u...
Indexed At
2026-08-10 04:16 UTC
View this version

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
}

Compare Other Versions

Lexicon Garden

@