space.remanso.recording

apoena.dev

Schema Diff

+115 -0

From

CID
bafyreie2zjvhgiw...
Indexed At
2026-08-02 19:35 UTC
View this version

To

CID
bafyreifezcxxjyj...
Indexed At
2026-08-06 21:00 UTC
View this version

Compatibility Analysis

Breaking Changes Detected

5 breaking changes, 17 non-breaking changes.

Breaking Changes (5)
  • RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "space.remanso.recording#transcript", src: "space.remanso.recording#transcript", tgt: "space.remanso.recording#transcript.createdAt", kind: "prop", name: Some("createdAt") }
  • RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "space.remanso.recording#transcript", src: "space.remanso.recording#transcript", tgt: "space.remanso.recording#transcript.text", kind: "prop", name: Some("text") }
  • RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "space.remanso.recording#transcriptSegment", src: "space.remanso.recording#transcriptSegment", tgt: "space.remanso.recording#transcriptSegment.endMs", kind: "prop", name: Some("endMs") }
  • RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "space.remanso.recording#transcriptSegment", src: "space.remanso.recording#transcriptSegment", tgt: "space.remanso.recording#transcriptSegment.startMs", kind: "prop", name: Some("startMs") }
  • RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "space.remanso.recording#transcriptSegment", src: "space.remanso.recording#transcriptSegment", tgt: "space.remanso.recording#transcriptSegment.text", kind: "prop", name: Some("text") }
Non-Breaking Changes (17)
  • AddedVertex AddedVertex { vertex_id: "space.remanso.recording#transcript" }
  • AddedVertex AddedVertex { vertex_id: "space.remanso.recording#transcript.createdAt" }
  • AddedVertex AddedVertex { vertex_id: "space.remanso.recording#transcript.segments" }
  • AddedVertex AddedVertex { vertex_id: "space.remanso.recording#transcript.segments:items" }
  • AddedVertex AddedVertex { vertex_id: "space.remanso.recording#transcript.text" }
  • AddedVertex AddedVertex { vertex_id: "space.remanso.recording#transcriptSegment" }
  • AddedVertex AddedVertex { vertex_id: "space.remanso.recording#transcriptSegment.endMs" }
  • AddedVertex AddedVertex { vertex_id: "space.remanso.recording#transcriptSegment.startMs" }
  • AddedVertex AddedVertex { vertex_id: "space.remanso.recording#transcriptSegment.text" }
  • AddedVertex AddedVertex { vertex_id: "space.remanso.recording:body.language" }
  • AddedVertex AddedVertex { vertex_id: "space.remanso.recording:body.transcript" }
  • AddedEdge AddedEdge { src: "space.remanso.recording#transcript", tgt: "space.remanso.recording#transcript.segments", kind: "prop", name: Some("segments") }
  • AddedEdge AddedEdge { src: "space.remanso.recording#transcript.segments", tgt: "space.remanso.recording#transcript.segments:items", kind: "items", name: None }
  • AddedEdge AddedEdge { src: "space.remanso.recording#transcript.segments:items", tgt: "space.remanso.recording#transcriptSegment", kind: "ref", name: None }
  • AddedEdge AddedEdge { src: "space.remanso.recording:body", tgt: "space.remanso.recording:body.language", kind: "prop", name: Some("language") }
  • AddedEdge AddedEdge { src: "space.remanso.recording:body", tgt: "space.remanso.recording:body.transcript", kind: "prop", name: Some("transcript") }
  • AddedEdge AddedEdge { src: "space.remanso.recording:body.transcript", tgt: "space.remanso.recording#transcript", kind: "ref", name: None }

Migration Guidance

Added Elements

  • AddedVertex { vertex_id: "space.remanso.recording#transcript" }
  • AddedVertex { vertex_id: "space.remanso.recording#transcript.createdAt" }
  • AddedVertex { vertex_id: "space.remanso.recording#transcript.segments" }
  • AddedVertex { vertex_id: "space.remanso.recording#transcript.segments:items" }
  • AddedVertex { vertex_id: "space.remanso.recording#transcript.text" }
  • AddedVertex { vertex_id: "space.remanso.recording#transcriptSegment" }
  • AddedVertex { vertex_id: "space.remanso.recording#transcriptSegment.endMs" }
  • AddedVertex { vertex_id: "space.remanso.recording#transcriptSegment.startMs" }
  • AddedVertex { vertex_id: "space.remanso.recording#transcriptSegment.text" }
  • AddedVertex { vertex_id: "space.remanso.recording:body.language" }
  • AddedVertex { vertex_id: "space.remanso.recording:body.transcript" }

Additional Notes

  • Breaking: RequiredEdgeAdded { vertex_id: "space.remanso.recording#transcript", src: "space.remanso.recording#transcript", tgt: "space.remanso.recording#transcript.createdAt", kind: "prop", name: Some("createdAt") }
  • Breaking: RequiredEdgeAdded { vertex_id: "space.remanso.recording#transcript", src: "space.remanso.recording#transcript", tgt: "space.remanso.recording#transcript.text", kind: "prop", name: Some("text") }
  • Breaking: RequiredEdgeAdded { vertex_id: "space.remanso.recording#transcriptSegment", src: "space.remanso.recording#transcriptSegment", tgt: "space.remanso.recording#transcriptSegment.endMs", kind: "prop", name: Some("endMs") }
  • Breaking: RequiredEdgeAdded { vertex_id: "space.remanso.recording#transcriptSegment", src: "space.remanso.recording#transcriptSegment", tgt: "space.remanso.recording#transcriptSegment.startMs", kind: "prop", name: Some("startMs") }
  • Breaking: RequiredEdgeAdded { vertex_id: "space.remanso.recording#transcriptSegment", src: "space.remanso.recording#transcriptSegment", tgt: "space.remanso.recording#transcriptSegment.text", kind: "prop", name: Some("text") }
  • Non-breaking: AddedEdge { src: "space.remanso.recording#transcript", tgt: "space.remanso.recording#transcript.segments", kind: "prop", name: Some("segments") }
  • Non-breaking: AddedEdge { src: "space.remanso.recording#transcript.segments", tgt: "space.remanso.recording#transcript.segments:items", kind: "items", name: None }
  • Non-breaking: AddedEdge { src: "space.remanso.recording#transcript.segments:items", tgt: "space.remanso.recording#transcriptSegment", kind: "ref", name: None }
  • Non-breaking: AddedEdge { src: "space.remanso.recording:body", tgt: "space.remanso.recording:body.language", kind: "prop", name: Some("language") }
  • Non-breaking: AddedEdge { src: "space.remanso.recording:body", tgt: "space.remanso.recording:body.transcript", kind: "prop", name: Some("transcript") }
  • Non-breaking: AddedEdge { src: "space.remanso.recording:body.transcript", tgt: "space.remanso.recording#transcript", kind: "ref", name: None }
1 1
{
2 2
  "$type": "com.atproto.lexicon.schema",
3 3
  "defs": {
4 4
    "credit": {
5 5
      "description": "One openly licensed work used in the recording, and where its terms live.",
6 6
      "properties": {
7 7
        "creator": {
8 8
          "maxLength": 1000,
9 9
          "type": "string"
10 10
        },
11 11
        "license": {
12 12
          "description": "The licence's short id, e.g. \"by\".",
13 13
          "maxLength": 64,
14 14
          "type": "string"
15 15
        },
16 16
        "licenseUrl": {
17 17
          "format": "uri",
18 18
          "type": "string"
19 19
        },
20 20
        "sourceUrl": {
21 21
          "description": "The work's landing page at its provider.",
22 22
          "format": "uri",
23 23
          "type": "string"
24 24
        },
25 25
        "title": {
26 26
          "maxLength": 1000,
27 27
          "type": "string"
28 28
        }
29 29
      },
30 30
      "required": [
31 31
        "title",
32 32
        "creator",
33 33
        "license",
34 34
        "licenseUrl",
35 35
        "sourceUrl"
36 36
      ],
37 37
      "type": "object"
38 38
    },
39 39
    "main": {
40 40
      "description": "An audio recording — a past stream, a podcast episode, a voice note. A recording at rkey R is the recording of the space.remanso.note at rkey R in the same repo: one note, at most one recording, paired by convention rather than by a field, so a reader that knows the note's did and rkey reaches the audio with a single getRecord. A recording whose rkey matches no note stands alone and belongs to nobody. Legacy path: a recording is also referenced from a note by at-uri embedded in the note's content.",
41 41
      "key": "tid",
42 42
      "record": {
43 43
        "properties": {
44 44
          "audio": {
45 45
            "accept": [
46 46
              "audio/*",
47 47
              "video/mp4",
48 48
              "video/webm"
49 49
            ],
50 50
            "description": "The recording itself. video/mp4 and video/webm are accepted alongside audio/* because a PDS sniffs the container rather than trusting the upload's Content-Type: an audio-only MP4 or M4A sniffs as video/mp4, and a sniffer that reads no further than the EBML magic calls an audio-only WebM video/webm.",
51 51
            "maxSize": 50000000,
52 52
            "type": "blob"
53 53
          },
54 54
          "createdAt": {
55 55
            "format": "datetime",
56 56
            "type": "string"
57 57
          },
58 58
          "credits": {
59 59
            "description": "Attribution for openly licensed music mixed into the recording. Only licences that require it are listed — a CC0 track is deliberately absent, because CC0 asks for nothing and an entry here would imply otherwise.",
60 60
            "items": {
61 61
              "ref": "#credit",
62 62
              "type": "ref"
63 63
            },
64 64
            "maxLength": 64,
65 65
            "type": "array"
66 66
          },
67 67
          "durationSec": {
68 68
            "description": "Playback length in seconds.",
69 69
            "type": "integer"
70 70
          },
71 +
          "language": {
72 +
            "description": "The language spoken in the recording. ISO 639-3, the same code space as space.remanso.note's `language`, so a note and its recording agree on how a language is spelled. A recording whose speech was never identified simply omits this.",
73 +
            "knownValues": [
74 +
              "afr",
75 +
              "ara",
76 +
              "aze",
77 +
              "bel",
78 +
              "ben",
79 +
              "bul",
80 +
              "cat",
81 +
              "ces",
82 +
              "ckb",
83 +
              "cmn",
84 +
              "dan",
85 +
              "deu",
86 +
              "ell",
87 +
              "eng",
88 +
              "est",
89 +
              "eus",
90 +
              "fin",
91 +
              "fra",
92 +
              "hau",
93 +
              "heb",
94 +
              "hin",
95 +
              "hrv",
96 +
              "hun",
97 +
              "hye",
98 +
              "ind",
99 +
              "isl",
100 +
              "ita",
101 +
              "jpn",
102 +
              "kat",
103 +
              "kaz",
104 +
              "kor",
105 +
              "lit",
106 +
              "mar",
107 +
              "mkd",
108 +
              "nld",
109 +
              "nob",
110 +
              "pes",
111 +
              "pol",
112 +
              "por",
113 +
              "ron",
114 +
              "run",
115 +
              "rus",
116 +
              "slk",
117 +
              "spa",
118 +
              "srp",
119 +
              "swe",
120 +
              "tgl",
121 +
              "tur",
122 +
              "ukr",
123 +
              "vie"
124 +
            ],
125 +
            "maxLength": 10,
126 +
            "type": "string"
127 +
          },
71 128
          "recordedAt": {
72 129
            "description": "When the audio was originally captured — a past stream's air date, not the upload time.",
73 130
            "format": "datetime",
74 131
            "type": "string"
75 132
          },
76 133
          "title": {
77 134
            "maxLength": 1000,
78 135
            "type": "string"
136 +
          },
137 +
          "transcript": {
138 +
            "ref": "#transcript",
139 +
            "type": "ref"
79 140
          }
80 141
        },
81 142
        "required": [
82 143
          "audio",
83 144
          "createdAt"
84 145
        ],
85 146
        "type": "object"
86 147
      },
87 148
      "type": "record"
149 +
    },
150 +
    "transcript": {
151 +
      "description": "What was said, as text. A recording is published before anything has transcribed it, so audio with no transcript is the normal starting state rather than an incomplete record — which is why this is optional and written by a later putRecord. `text` is the whole transcript in reading order and is always present; `segments` is that same text cut into timestamped spans. The two never disagree: a client renders either one without reconciling them, and a writer that edits one rewrites both.",
152 +
      "properties": {
153 +
        "createdAt": {
154 +
          "description": "When this transcript was written, which is later than the recording's own createdAt, and is bumped on every correction.",
155 +
          "format": "datetime",
156 +
          "type": "string"
157 +
        },
158 +
        "segments": {
159 +
          "description": "The transcript cut into timestamped spans, one paragraph each — the granularity a reader scans and seeks by, not the two-second slivers a speech model emits. Absent when the audio yielded no usable timestamps, which happens on very short clips.",
160 +
          "items": {
161 +
            "ref": "#transcriptSegment",
162 +
            "type": "ref"
163 +
          },
164 +
          "maxLength": 4096,
165 +
          "type": "array"
166 +
        },
167 +
        "text": {
168 +
          "description": "The transcript in reading order, paragraphs separated by a blank line. Equal to `segments` joined the same way, when segments are present.",
169 +
          "maxLength": 100000,
170 +
          "type": "string"
171 +
        }
172 +
      },
173 +
      "required": [
174 +
        "text",
175 +
        "createdAt"
176 +
      ],
177 +
      "type": "object"
178 +
    },
179 +
    "transcriptSegment": {
180 +
      "description": "One timestamped span of the transcript. Offsets are milliseconds from the start of the audio: the lexicon data model has no float, and rounding to whole seconds would land a seek target after the words the timestamp labels.",
181 +
      "properties": {
182 +
        "endMs": {
183 +
          "description": "Offset from the start of the audio, in milliseconds. Never before `startMs`.",
184 +
          "minimum": 0,
185 +
          "type": "integer"
186 +
        },
187 +
        "startMs": {
188 +
          "description": "Offset from the start of the audio, in milliseconds.",
189 +
          "minimum": 0,
190 +
          "type": "integer"
191 +
        },
192 +
        "text": {
193 +
          "maxLength": 10000,
194 +
          "type": "string"
195 +
        }
196 +
      },
197 +
      "required": [
198 +
        "startMs",
199 +
        "endMs",
200 +
        "text"
201 +
      ],
202 +
      "type": "object"
88 203
    }
89 204
  },
90 205
  "id": "space.remanso.recording",
91 206
  "lexicon": 1
92 207
}

Compare Other Versions

Lexicon Garden

@