at.kotoba.session
Schema Diff
+8 -4
Compatibility Analysis
Breaking Changes Detected
1 breaking change, 0 non-breaking changes.
Breaking Changes (1)
- ConstraintTightened ConstraintTightened { vertex_id: "at.kotoba.session#card.mode", sort: "knownValues", old_value: "[\"tap\",\"type\"]", new_value: "[\"tap\",\"type\",\"meaning\",\"choice\"]" }
Migration Guidance
Constraint Changes
- ConstraintTightened ConstraintTightened { vertex_id: "at.kotoba.session#card.mode", sort: "knownValues", old_value: "[\"tap\",\"type\"]", new_value: "[\"tap\",\"type\",\"meaning\",\"choice\"]" }
1
1
{
2
2
"$type": "com.atproto.lexicon.schema",
3
3
"defs": {
4
4
"card": {
5
5
"description": "One answered card. `answer` is what the user produced (the correct reading is derivable by joining packRef+glyph; not stored, per SPEC §3.2).",
6
6
"properties": {
7
7
"answer": {
8
8
"description": "What the user answered. Optional: may be absent on a skip/timeout (app-side `given` is nullable).",
9
9
"type": "string"
10
10
},
11
11
"correct": {
12
12
"type": "boolean"
13
13
},
14
14
"distractors": {
15
-
"description": "Tap mode only; the romaji offered. Absent for type.",
15
+
"description": "The other options offered beside the answer: romaji on a tap card, English glosses on a meaning card. Absent for type, which has no grid.",
16
16
"items": {
17
17
"type": "string"
18
18
},
19
19
"type": "array"
20
20
},
21
21
"glyph": {
22
+
"description": "The item's SRS state key: the prompt glyph for a recognition card, `grammar:<id>` for a grammar one (which has no glyph).",
22
23
"type": "string"
23
24
},
24
25
"mode": {
26
+
"description": "How the card was answered. tap = pick the romaji reading, type = write it out, meaning = pick the English gloss (a word, or a derived verb form — see `type`), choice = pick the answer to a grammar prompt from its authored options.",
25
27
"knownValues": [
26
28
"tap",
27
-
"type"
29
+
"type",
30
+
"meaning",
31
+
"choice"
28
32
],
29
33
"type": "string"
30
34
},
31
35
"parseMs": {
32
36
"description": "render -> first response/keystroke.",
33
37
"type": "integer"
34
38
},
35
39
"totalMs": {
36
40
"description": "render -> submit (tap: == parseMs).",
37
41
"type": "integer"
38
42
},
39
43
"ts": {
40
44
"format": "datetime",
41
45
"type": "string"
42
46
},
43
47
"type": {
44
-
"description": "Open string; matches the pack item's type.",
48
+
"description": "Open string; matches the pack item's type. `conjugation` is a de-conjugation card (#146) — a verb form derived at session time rather than authored in the pack, keyed on the conjugated surface.",
45
49
"type": "string"
46
50
}
47
51
},
48
52
"required": [
49
53
"glyph",
50
54
"type",
51
55
"mode",
52
56
"correct",
53
57
"parseMs",
54
58
"totalMs",
55
59
"ts"
56
60
],
57
61
"type": "object"
58
62
},
59
63
"config": {
60
64
"description": "The setup choices that drove the session (enables Drill-again + analytics slicing).",
61
65
"properties": {
62
66
"cardStyle": {
63
67
"description": "Open. genko | hanko | ma.",
64
68
"type": "string"
65
69
},
66
70
"focus": {
67
71
"description": "Open. all | hiragana | katakana.",
68
72
"type": "string"
69
73
},
70
74
"length": {
71
75
"description": "10 | 20 | full-count.",
72
76
"type": "integer"
73
77
},
74
78
"recall": {
75
-
"description": "Open. tap | mixed | type.",
79
+
"description": "Open. tap | mixed | type | meaning | read (type + meaning).",
76
80
"type": "string"
77
81
}
78
82
},
79
83
"required": [
80
84
"length",
81
85
"focus",
82
86
"recall",
83
87
"cardStyle"
84
88
],
85
89
"type": "object"
86
90
},
87
91
"main": {
88
92
"description": "One practice session: the full per-card interaction array, the config that drove it, and session-level rollups. Append-only stack; TID rkeys (time-ordered).",
89
93
"key": "tid",
90
94
"record": {
91
95
"properties": {
92
96
"cards": {
93
97
"items": {
94
98
"ref": "#card",
95
99
"type": "ref"
96
100
},
97
101
"type": "array"
98
102
},
99
103
"config": {
100
104
"ref": "#config",
101
105
"type": "ref"
102
106
},
103
107
"endedAt": {
104
108
"format": "datetime",
105
109
"type": "string"
106
110
},
107
111
"packRef": {
108
112
"description": "at:// URI of the lesson.pack record that drove this session.",
109
113
"format": "at-uri",
110
114
"type": "string"
111
115
},
112
116
"rollup": {
113
117
"ref": "#rollup",
114
118
"type": "ref"
115
119
},
116
120
"startedAt": {
117
121
"format": "datetime",
118
122
"type": "string"
119
123
}
120
124
},
121
125
"required": [
122
126
"startedAt",
123
127
"endedAt",
124
128
"cards",
125
129
"rollup"
126
130
],
127
131
"type": "object"
128
132
},
129
133
"type": "record"
130
134
},
131
135
"rollup": {
132
136
"description": "Precomputed so range scans avoid touching the per-card array.",
133
137
"properties": {
134
138
"byType": {
135
139
"description": "Map keyed by type string -> { n, correct }. `unknown` because lexicons have no dynamic-key map type (see README).",
136
140
"type": "unknown"
137
141
},
138
142
"correct": {
139
143
"type": "integer"
140
144
},
141
145
"medianParseMs": {
142
146
"type": "integer"
143
147
},
144
148
"n": {
145
149
"type": "integer"
146
150
}
147
151
},
148
152
"required": [
149
153
"n",
150
154
"correct",
151
155
"medianParseMs"
152
156
],
153
157
"type": "object"
154
158
}
155
159
},
156
160
"id": "at.kotoba.session",
157
161
"lexicon": 1
158
162
}