at.kotoba.session

kotoba.at

Documentation

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).

main record

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).

Record Key tid Timestamp-based ID

Properties

cards array of ref #card Required

No description available.

config ref #config Optional

No description available.

endedAt string datetime Required

An RFC 3339 formatted timestamp.

packRef string at-uri Optional

at:// URI of the lesson.pack record that drove this session.

rollup ref #rollup Required

No description available.

startedAt string datetime Required

An RFC 3339 formatted timestamp.

View raw schema
{
  "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).",
  "key": "tid",
  "record": {
    "properties": {
      "cards": {
        "items": {
          "ref": "#card",
          "type": "ref"
        },
        "type": "array"
      },
      "config": {
        "ref": "#config",
        "type": "ref"
      },
      "endedAt": {
        "format": "datetime",
        "type": "string"
      },
      "packRef": {
        "description": "at:// URI of the lesson.pack record that drove this session.",
        "format": "at-uri",
        "type": "string"
      },
      "rollup": {
        "ref": "#rollup",
        "type": "ref"
      },
      "startedAt": {
        "format": "datetime",
        "type": "string"
      }
    },
    "required": [
      "startedAt",
      "endedAt",
      "cards",
      "rollup"
    ],
    "type": "object"
  },
  "type": "record"
}
card object

One answered card. `answer` is what the user produced (the correct reading is derivable by joining packRef+glyph; not stored, per SPEC §3.2).

Properties

answer string Optional

What the user answered. Optional: may be absent on a skip/timeout (app-side `given` is nullable).

correct boolean Required

No description available.

distractors array of string Optional

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.

glyph string Required

The item's SRS state key: the prompt glyph for a recognition card, `grammar:<id>` for a grammar one (which has no glyph).

mode string Required

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.

Known values: tap, type, meaning, choice
parseMs integer Required

render -> first response/keystroke.

totalMs integer Required

render -> submit (tap: == parseMs).

ts string datetime Required

An RFC 3339 formatted timestamp.

type string Required

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.

View raw schema
{
  "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).",
  "properties": {
    "answer": {
      "description": "What the user answered. Optional: may be absent on a skip/timeout (app-side `given` is nullable).",
      "type": "string"
    },
    "correct": {
      "type": "boolean"
    },
    "distractors": {
      "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.",
      "items": {
        "type": "string"
      },
      "type": "array"
    },
    "glyph": {
      "description": "The item's SRS state key: the prompt glyph for a recognition card, `grammar:<id>` for a grammar one (which has no glyph).",
      "type": "string"
    },
    "mode": {
      "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.",
      "knownValues": [
        "tap",
        "type",
        "meaning",
        "choice"
      ],
      "type": "string"
    },
    "parseMs": {
      "description": "render -> first response/keystroke.",
      "type": "integer"
    },
    "totalMs": {
      "description": "render -> submit (tap: == parseMs).",
      "type": "integer"
    },
    "ts": {
      "format": "datetime",
      "type": "string"
    },
    "type": {
      "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.",
      "type": "string"
    }
  },
  "required": [
    "glyph",
    "type",
    "mode",
    "correct",
    "parseMs",
    "totalMs",
    "ts"
  ],
  "type": "object"
}
config object

The setup choices that drove the session (enables Drill-again + analytics slicing).

Properties

cardStyle string Required

Open. genko | hanko | ma.

focus string Required

Open. all | hiragana | katakana.

length integer Required

10 | 20 | full-count.

recall string Required

Open. tap | mixed | type | meaning | read (type + meaning).

View raw schema
{
  "description": "The setup choices that drove the session (enables Drill-again + analytics slicing).",
  "properties": {
    "cardStyle": {
      "description": "Open. genko | hanko | ma.",
      "type": "string"
    },
    "focus": {
      "description": "Open. all | hiragana | katakana.",
      "type": "string"
    },
    "length": {
      "description": "10 | 20 | full-count.",
      "type": "integer"
    },
    "recall": {
      "description": "Open. tap | mixed | type | meaning | read (type + meaning).",
      "type": "string"
    }
  },
  "required": [
    "length",
    "focus",
    "recall",
    "cardStyle"
  ],
  "type": "object"
}
rollup object

Precomputed so range scans avoid touching the per-card array.

Properties

byType unknown Optional

Map keyed by type string -> { n, correct }. `unknown` because lexicons have no dynamic-key map type (see README).

correct integer Required

No description available.

medianParseMs integer Required

No description available.

n integer Required

No description available.

View raw schema
{
  "description": "Precomputed so range scans avoid touching the per-card array.",
  "properties": {
    "byType": {
      "description": "Map keyed by type string -> { n, correct }. `unknown` because lexicons have no dynamic-key map type (see README).",
      "type": "unknown"
    },
    "correct": {
      "type": "integer"
    },
    "medianParseMs": {
      "type": "integer"
    },
    "n": {
      "type": "integer"
    }
  },
  "required": [
    "n",
    "correct",
    "medianParseMs"
  ],
  "type": "object"
}

Lexicon Garden

@