at.kotoba.lesson.pack
Lesson content the app drills. Append-only stack; latest = active. Free-form by design: a known core the UI reads + open `meta`/`defaults` round-tripped untouched (SPEC §3.1a). This record body IS the upload interchange shape (lessons/pack.schema.json).
Details · record, key tid
| Kind | record |
|---|---|
| Record key | tid |
| Authority | lesson.kotoba.at |
| Indexed |
Record
record · key tidProperties
createdAt
stringISO 8601. NOTE: the app currently stamps a date-only string (YYYY-MM-DD), not a datetime — left unformatted here pending reconciliation (see README).
meta
unknownPack-level open extension; UI ignores, round-trips.
phase
stringOpen. kana | vocab | grammar.
rationale
stringscript
arrayDeclared scripts; drives chips + Focus. The scripts the glyphs are WRITTEN in — for a `word` item that is its kana script, not "word" (#99). Derived the same way if omitted; a word that is unsegmentable or mixes both kana falls back to "word". A declared script is cleaned by the app (#99): "word", junk and duplicates are dropped and the rest kept; "word" returns only if derivation finds an item with no derivable script.
#defaults
objectPack-level drill defaults (SPEC §4). Open additional keys round-trip via the pack `meta`.
Properties
katakanaMultiplier
integerQueue weight multiplier for katakana. Fixed-point ×10000 (e.g. 1.5 -> 15000); no float type.
tapToTypeBox
integerLeitner box at/above which a glyph may graduate tap -> type.
minimum: 1maximum: 5
#forms
objectAuthored conjugation surfaces, keyed by the form names in src/drill/conjugate.ts. Kana only — the kanji surface is derived from the item's `kanji` form. A key this build does not know is ignored, so a form added later needs no lexicon change.
#item
objectA card. A discriminated union on `type` (#1), flattened into one object because lexicons have no oneOf: a RECOGNITION item (hiragana | katakana | kanji | word) requires glyph + romaji, a GRAMMAR item (particle | contraction | usage | sentence) requires id + prompt + answer. `conjugation` is a RECOGNITION type (#146): a derived verb surface, so it carries glyph + romaji like any word. Only `type` can be required here; the per-branch requiredness is enforced by lessons/pack.schema.json (JSON Schema if/then) and src/packs/validate.ts, which is what every reader of this record already routes through.
Properties
accept
arrayGRAMMAR branch, optional. Alternative answers graded correct beside `answer` — casual forms routinely have two natural ones. Exact-match grading is unchanged; the accepted set just has more members.
answer
stringGRAMMAR branch, required there. The one canonical answer; graded by exact compare after trim.
choices
arrayGRAMMAR branch, optional. Authored options for the choice grid (#145); contains `answer` when present. Never empty — the app drops an empty or wrong-typed list at the upload boundary rather than writing one.
confusableWith
arrayROMAJI (not glyphs) of same-script confusers; cold-start distractor seed.
forms
refAuthored kana surfaces for the forms no rule derives (#136) — an irregular's whole paradigm, or one form of an otherwise regular verb (iku's itte). A form with no entry falls back to the derivation.
gloss
stringEnglish meaning; recommended for words/kanji, and for a grammar item it is the meaning of the whole line.
glyph
stringRECOGNITION branch, required there. 1+ chars: single kana, word, or kanji.
group
integerVerb conjugation class (#136): 1 godan, 2 ichidan, 3 irregular. Word items only. The app derives every form from it (src/drill/conjugate.ts) instead of the pack authoring them.
minimum: 1maximum: 3
id
stringGRAMMAR branch, required there and unique within the pack. The SRS state map is glyph-keyed and a grammar item has no glyph, so it is keyed `grammar:<id>` (#145). Uniqueness is enforced by validate.ts, not here.
kanji
stringWritten form in kanji (or kanji + okurigana) of a kana word — にほんじん -> 日本人. The below-hint path is passive (#125); a usable ruby meaning prompt records the separate kanji-recognition lane (#171). Omit where there is no kanji form (gairaigo) or the word is normally written in kana.
meta
unknownItem-level open extension; UI ignores, round-trips.
prompt
stringGRAMMAR branch, required there. The sentence, with the blank written by the author (U+FF3F). Opaque to this layer: it may carry `{kanji|kana}` ruby markup (#139).
romaji
stringRECOGNITION branch, required there. Expected reading; lowercase Hepburn, exact case-insensitive match.
row
stringGojuon row label, single kana and combination kana (yoon + extended) only.
ruby
stringOptional authored furigana boundaries for a recognition item, using `{base|reading}` markup. Used only when it reconstructs the plain `kanji` form and `glyph` reading; unusable markup falls back safely.
Open. Recognition: hiragana | katakana | kanji | word | conjugation (#146, a derived verb surface). Grammar (#1): particle | contraction | usage | sentence.
weight
integerOptional author priority override. Fixed-point ×10000 (e.g. 1.8 -> 18000); lexicons have no float type. App scales at the record edge (see README).
Similar lexicons
semantic matchLexicons whose schemas describe something close to this one. Check them before publishing a new one that overlaps.
-
at.kotoba.session
recordOne practice session: the full per-card interaction array, the config that drove it, and session-level rollups. Append-only stack; TID rkeys (time-ordered).