org.anthers.work

anthers.org

Schema Diff

+84 -1

From

CID
bafyreif6j3ek2rk...
Indexed At
2026-09-11 02:13 UTC
View this version

To

CID
bafyreicvsjl4py7...
Indexed At
2026-09-23 03:01 UTC
View this version

Compatibility Analysis

Breaking Changes Detected

4 breaking changes, 25 non-breaking changes.

Breaking Changes (4)
  • RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "org.anthers.work#credit", src: "org.anthers.work#credit", tgt: "org.anthers.work#credit.types", kind: "prop", name: Some("types") }
  • RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "org.anthers.work#didContributor", src: "org.anthers.work#didContributor", tgt: "org.anthers.work#didContributor.did", kind: "prop", name: Some("did") }
  • RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "org.anthers.work#namedContributor", src: "org.anthers.work#namedContributor", tgt: "org.anthers.work#namedContributor.name", kind: "prop", name: Some("name") }
  • ConstraintTightened ConstraintTightened { vertex_id: "org.anthers.work:body.kind", sort: "knownValues", old_value: "[\"text\",\"video\",\"audio\",\"image\",\"ebook\",\"game\",\"software\",\"physical\",\"service\"]", new_value: "[\"text\",\"video\",\"music\",\"audio\",\"image\",\"comic\",\"ebook\",\"game\",\"software\",\"physical\",\"service\"]" }
Non-Breaking Changes (25)
  • AddedVertex AddedVertex { vertex_id: "org.anthers.work#credit" }
  • AddedVertex AddedVertex { vertex_id: "org.anthers.work#credit.contributor" }
  • AddedVertex AddedVertex { vertex_id: "org.anthers.work#credit.contributor:variant0" }
  • AddedVertex AddedVertex { vertex_id: "org.anthers.work#credit.contributor:variant1" }
  • AddedVertex AddedVertex { vertex_id: "org.anthers.work#credit.role" }
  • AddedVertex AddedVertex { vertex_id: "org.anthers.work#credit.types" }
  • AddedVertex AddedVertex { vertex_id: "org.anthers.work#credit.types:items" }
  • AddedVertex AddedVertex { vertex_id: "org.anthers.work#didContributor" }
  • AddedVertex AddedVertex { vertex_id: "org.anthers.work#didContributor.did" }
  • AddedVertex AddedVertex { vertex_id: "org.anthers.work#namedContributor" }
  • AddedVertex AddedVertex { vertex_id: "org.anthers.work#namedContributor.name" }
  • AddedVertex AddedVertex { vertex_id: "org.anthers.work#namedContributor.url" }
  • AddedVertex AddedVertex { vertex_id: "org.anthers.work:body.credits" }
  • AddedVertex AddedVertex { vertex_id: "org.anthers.work:body.credits:items" }
  • AddedEdge AddedEdge { src: "org.anthers.work#credit", tgt: "org.anthers.work#credit.contributor", kind: "prop", name: Some("contributor") }
  • AddedEdge AddedEdge { src: "org.anthers.work#credit", tgt: "org.anthers.work#credit.role", kind: "prop", name: Some("role") }
  • AddedEdge AddedEdge { src: "org.anthers.work#credit.contributor", tgt: "org.anthers.work#credit.contributor:variant0", kind: "variant", name: Some("#didContributor") }
  • AddedEdge AddedEdge { src: "org.anthers.work#credit.contributor", tgt: "org.anthers.work#credit.contributor:variant1", kind: "variant", name: Some("#namedContributor") }
  • AddedEdge AddedEdge { src: "org.anthers.work#credit.contributor:variant0", tgt: "org.anthers.work#didContributor", kind: "ref", name: None }
  • AddedEdge AddedEdge { src: "org.anthers.work#credit.contributor:variant1", tgt: "org.anthers.work#namedContributor", kind: "ref", name: None }
  • AddedEdge AddedEdge { src: "org.anthers.work#credit.types", tgt: "org.anthers.work#credit.types:items", kind: "items", name: None }
  • AddedEdge AddedEdge { src: "org.anthers.work#namedContributor", tgt: "org.anthers.work#namedContributor.url", kind: "prop", name: Some("url") }
  • AddedEdge AddedEdge { src: "org.anthers.work:body", tgt: "org.anthers.work:body.credits", kind: "prop", name: Some("credits") }
  • AddedEdge AddedEdge { src: "org.anthers.work:body.credits", tgt: "org.anthers.work:body.credits:items", kind: "items", name: None }
  • AddedEdge AddedEdge { src: "org.anthers.work:body.credits:items", tgt: "org.anthers.work#credit", kind: "ref", name: None }

Migration Guidance

Added Elements

  • AddedVertex { vertex_id: "org.anthers.work#credit" }
  • AddedVertex { vertex_id: "org.anthers.work#credit.contributor" }
  • AddedVertex { vertex_id: "org.anthers.work#credit.contributor:variant0" }
  • AddedVertex { vertex_id: "org.anthers.work#credit.contributor:variant1" }
  • AddedVertex { vertex_id: "org.anthers.work#credit.role" }
  • AddedVertex { vertex_id: "org.anthers.work#credit.types" }
  • AddedVertex { vertex_id: "org.anthers.work#credit.types:items" }
  • AddedVertex { vertex_id: "org.anthers.work#didContributor" }
  • AddedVertex { vertex_id: "org.anthers.work#didContributor.did" }
  • AddedVertex { vertex_id: "org.anthers.work#namedContributor" }
  • AddedVertex { vertex_id: "org.anthers.work#namedContributor.name" }
  • AddedVertex { vertex_id: "org.anthers.work#namedContributor.url" }
  • AddedVertex { vertex_id: "org.anthers.work:body.credits" }
  • AddedVertex { vertex_id: "org.anthers.work:body.credits:items" }

Constraint Changes

  • ConstraintTightened ConstraintTightened { vertex_id: "org.anthers.work:body.kind", sort: "knownValues", old_value: "[\"text\",\"video\",\"audio\",\"image\",\"ebook\",\"game\",\"software\",\"physical\",\"service\"]", new_value: "[\"text\",\"video\",\"music\",\"audio\",\"image\",\"comic\",\"ebook\",\"game\",\"software\",\"physical\",\"service\"]" }

Additional Notes

  • Breaking: RequiredEdgeAdded { vertex_id: "org.anthers.work#namedContributor", src: "org.anthers.work#namedContributor", tgt: "org.anthers.work#namedContributor.name", kind: "prop", name: Some("name") }
  • Breaking: RequiredEdgeAdded { vertex_id: "org.anthers.work#credit", src: "org.anthers.work#credit", tgt: "org.anthers.work#credit.types", kind: "prop", name: Some("types") }
  • Breaking: RequiredEdgeAdded { vertex_id: "org.anthers.work#didContributor", src: "org.anthers.work#didContributor", tgt: "org.anthers.work#didContributor.did", kind: "prop", name: Some("did") }
  • Non-breaking: AddedEdge { src: "org.anthers.work#credit", tgt: "org.anthers.work#credit.contributor", kind: "prop", name: Some("contributor") }
  • Non-breaking: AddedEdge { src: "org.anthers.work#credit", tgt: "org.anthers.work#credit.role", kind: "prop", name: Some("role") }
  • Non-breaking: AddedEdge { src: "org.anthers.work#credit.contributor", tgt: "org.anthers.work#credit.contributor:variant0", kind: "variant", name: Some("#didContributor") }
  • Non-breaking: AddedEdge { src: "org.anthers.work#credit.contributor", tgt: "org.anthers.work#credit.contributor:variant1", kind: "variant", name: Some("#namedContributor") }
  • Non-breaking: AddedEdge { src: "org.anthers.work#credit.contributor:variant0", tgt: "org.anthers.work#didContributor", kind: "ref", name: None }
  • Non-breaking: AddedEdge { src: "org.anthers.work#credit.contributor:variant1", tgt: "org.anthers.work#namedContributor", kind: "ref", name: None }
  • Non-breaking: AddedEdge { src: "org.anthers.work#credit.types", tgt: "org.anthers.work#credit.types:items", kind: "items", name: None }
  • Non-breaking: AddedEdge { src: "org.anthers.work#namedContributor", tgt: "org.anthers.work#namedContributor.url", kind: "prop", name: Some("url") }
  • Non-breaking: AddedEdge { src: "org.anthers.work:body", tgt: "org.anthers.work:body.credits", kind: "prop", name: Some("credits") }
  • Non-breaking: AddedEdge { src: "org.anthers.work:body.credits", tgt: "org.anthers.work:body.credits:items", kind: "items", name: None }
  • Non-breaking: AddedEdge { src: "org.anthers.work:body.credits:items", tgt: "org.anthers.work#credit", kind: "ref", name: None }
1 1
{
2 2
  "$type": "com.atproto.lexicon.schema",
3 3
  "defs": {
4 4
    "access": {
5 5
      "description": "Whether reaching this work costs anything. ⚠️ A display hint and NEVER an authorization: it describes what a stranger would find, not what any particular viewer is entitled to, and a consumer that treats it as permission is wrong. An object rather than a bare string so that further context — such as where access is granted — can be added later without a breaking change.",
6 6
      "properties": {
7 7
        "state": {
8 8
          "description": "`open` — anyone may reach the work at no cost. `gated` — reaching it requires supporting the creator or buying it, on terms shown on the work's own page. Terms themselves are deliberately absent: a price shown apart from the total a person actually pays is misleading, and this record cannot control how a consumer renders it.",
9 9
          "knownValues": [
10 10
            "open",
11 11
            "gated"
12 12
          ],
13 13
          "maxLength": 32,
14 14
          "type": "string"
15 15
        }
16 16
      },
17 17
      "required": [
18 18
        "state"
19 19
      ],
20 20
      "type": "object"
21 21
    },
22 +
    "credit": {
23 +
      "description": "One credit on the work: a contribution, its kind, and where a person made it, who. The three parts answer different questions and are kept apart so each can be absent on its own terms. `types` is the only required one — a credit must assert something.",
24 +
      "properties": {
25 +
        "contributor": {
26 +
          "description": "Who is credited. A DID names an on-network identity and is withheld until that identity accepts (see `org.anthers.creditAcceptance`); a name names an off-network contributor and is published as entered. A union rather than a bare string or a single object, so a third contributor kind can join later as a permitted addition. Optional: a credit with no `created` among its types may name nobody — a license or a machine makes nothing a person owns. Required whenever `created` is among the types, alone or in a blend — anything a human made must name who.",
27 +
          "refs": [
28 +
            "#didContributor",
29 +
            "#namedContributor"
30 +
          ],
31 +
          "type": "union"
32 +
        },
33 +
        "role": {
34 +
          "description": "The contribution this credit names, as a freeform title in the industry's own words — 'Written by', 'Cut by', 'Sound recording'. Freeform rather than a fixed list, because the useful roles differ by medium and a closed set would force every work into categories that fit none of them. Optional: a credit that is only a type assertion (a bare `ai` row, or an anonymous license) may leave the role unnamed.",
35 +
          "maxGraphemes": 120,
36 +
          "maxLength": 1200,
37 +
          "type": "string"
38 +
        },
39 +
        "types": {
40 +
          "description": "The kind(s) of contribution, published as entered. `created` — a person made this part. `licensed` — this part is pre-existing material used under a right (the source may be named or not, at the creator's choice; many licenses do not require attribution). `ai` — this part was machine-made: it records THAT it was, never which model, because a model owns nothing and can be granted nothing. An open set on purpose: a `created+ai` blend and the other non-empty subsets each mean what they say, and Anthers blesses no canonical 'counts as AI' reading of a blend — whether one clears a filter is the reader's own call, and two filters reading a blend opposite ways is a feature, not a defect.",
41 +
          "items": {
42 +
            "knownValues": [
43 +
              "created",
44 +
              "licensed",
45 +
              "ai"
46 +
            ],
47 +
            "maxLength": 16,
48 +
            "type": "string"
49 +
          },
50 +
          "minLength": 1,
51 +
          "type": "array"
52 +
        }
53 +
      },
54 +
      "required": [
55 +
        "types"
56 +
      ],
57 +
      "type": "object"
58 +
    },
59 +
    "didContributor": {
60 +
      "description": "A contributor identified by an on-network identity — their own DID. Naming one is a public claim about a third party, so it is withheld from the work record until that identity accepts it; an unconfirmed claim rendered as fact would travel somewhere a later correction cannot follow.",
61 +
      "properties": {
62 +
        "did": {
63 +
          "description": "The contributor's DID.",
64 +
          "format": "did",
65 +
          "type": "string"
66 +
        }
67 +
      },
68 +
      "required": [
69 +
        "did"
70 +
      ],
71 +
      "type": "object"
72 +
    },
22 73
    "main": {
23 74
      "description": "One entry in a creator's Catalog — a game, video, album, essay, or other work they have released. This record is the public LISTING for that work: it says what the work is and where to reach it, and it never carries the work itself. It exists only while the work is publicly listed, and whether a particular person may open the work is decided by the service hosting it, never by this record.",
24 75
      "key": "tid",
25 76
      "record": {
26 77
        "properties": {
27 78
          "access": {
28 79
            "ref": "#access",
29 80
            "type": "ref"
30 81
          },
82 +
          "credits": {
83 +
            "description": "Who made this work and what of it they made — the creator's own liner notes. Optional and additive: a work with no credits simply lists none, which says nothing against it (credits are asserted, never assumed). A credit naming an on-network identity by DID is withheld until that identity accepts it (see `org.anthers.creditAcceptance`), because a public claim about a third party should not be made in their name without their consent. The `types` flags are published exactly as the creator entered them — including `ai` — so a stranger can build a real filter on machine-made work.",
84 +
            "items": {
85 +
              "ref": "#credit",
86 +
              "type": "ref"
87 +
            },
88 +
            "maxLength": 100,
89 +
            "type": "array"
90 +
          },
31 91
          "description": {
32 92
            "description": "The creator's own summary of the work. Plain text, so that every consumer can render it safely without a sanitizer.",
33 93
            "maxGraphemes": 3000,
34 94
            "maxLength": 30000,
35 95
            "type": "string"
36 96
          },
37 97
          "kind": {
38 -
            "description": "What sort of work this is, in the sense of how it is handled — which player or reader opens it. Named `kind` rather than `type` because a record already carries `$type`, and two differently-scoped `type` fields in one object is a needless trap for anyone reading the JSON. This is an open set: consumers must accept values not listed here, because new mediums are added over time.",
98 +
            "description": "What sort of work this is, in the sense of how it is handled — which player or reader opens it. Named `kind` rather than `type` because a record already carries `$type`, and two differently-scoped `type` fields in one object is a needless trap for anyone reading the JSON. `comic` and `music` are narrower than `ebook` and `audio`, which mean a book that is not a comic and audio that is not music. This is an open set: consumers must accept values not listed here, because new mediums are added over time.",
39 99
            "knownValues": [
40 100
              "text",
41 101
              "video",
102 +
              "music",
42 103
              "audio",
43 104
              "image",
105 +
              "comic",
44 106
              "ebook",
45 107
              "game",
46 108
              "software",
47 109
              "physical",
48 110
              "service"
49 111
            ],
50 112
            "maxLength": 64,
51 113
            "type": "string"
52 114
          },
53 115
          "releasedAt": {
54 116
            "description": "When the work was released to the public. This is the work's own date and the only one the record carries — record-creation time is already encoded in the record key, so a separate field for it would be a second, weaker answer to a question the key already answers.",
55 117
            "format": "datetime",
56 118
            "type": "string"
57 119
          },
58 120
          "title": {
59 121
            "description": "The work's name, as its creator wrote it. Plain text for the same reason the description is: every consumer should be able to render it without a sanitizer. Required and never empty — a listing that names nothing is worse than no listing, so a work without a title is not published rather than published anonymously.",
60 122
            "maxGraphemes": 300,
61 123
            "maxLength": 3000,
62 124
            "type": "string"
63 125
          },
64 126
          "url": {
65 127
            "description": "Where this work can be reached. Usually its page on the service hosting it; a creator hosting their own Catalog points at their own. Deliberately not assumed to be an anthers.org address, because a creator's work outliving any one host is the point.",
66 128
            "format": "uri",
67 129
            "type": "string"
68 130
          }
69 131
        },
70 132
        "required": [
71 133
          "kind",
72 134
          "title",
73 135
          "url",
74 136
          "releasedAt"
75 137
        ],
76 138
        "type": "object"
77 139
      },
78 140
      "type": "record"
141 +
    },
142 +
    "namedContributor": {
143 +
      "description": "A contributor with no network identity, named by the creator — an off-platform collaborator, or a source by title. Stays unconfirmed by construction: there is no actor who can accept.",
144 +
      "properties": {
145 +
        "name": {
146 +
          "description": "The contributor or source, as the creator entered it.",
147 +
          "maxGraphemes": 300,
148 +
          "maxLength": 3000,
149 +
          "type": "string"
150 +
        },
151 +
        "url": {
152 +
          "description": "A link giving context — a portfolio, a source page.",
153 +
          "format": "uri",
154 +
          "maxLength": 2048,
155 +
          "type": "string"
156 +
        }
157 +
      },
158 +
      "required": [
159 +
        "name"
160 +
      ],
161 +
      "type": "object"
79 162
    }
80 163
  },
81 164
  "id": "org.anthers.work",
82 165
  "lexicon": 1
83 166
}

Compare Other Versions

Lexicon Garden

@