# at.kotoba.lesson.pack

> Published by [kotoba.at](https://lexicon.garden/identity/did:plc:o5f3cgna5sku4p6iitld6mxs)

✓ This is the authoritative definition for this NSID.

## Links

- [View on Lexicon Garden](https://lexicon.garden/lexicon/did:plc:o5f3cgna5sku4p6iitld6mxs/at.kotoba.lesson.pack)
- [Documentation](https://lexicon.garden/lexicon/did:plc:o5f3cgna5sku4p6iitld6mxs/at.kotoba.lesson.pack/docs)
- [Examples](https://lexicon.garden/lexicon/did:plc:o5f3cgna5sku4p6iitld6mxs/at.kotoba.lesson.pack/examples)

## Definitions

### `at.kotoba.lesson.pack#item`

**Type**: `object`

A card. Core: glyph/romaji/type. `glyph` is 1+ chars (single kana, word, or kanji).

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `row` | `string` | No | Gojuon row label, single kana only. |
| `meta` | `unknown` | No | Item-level open extension; UI ignores, round-trips. |
| `type` | `string` | Yes | Open. hiragana \| katakana \| kanji \| word. |
| `gloss` | `string` | No | English meaning; recommended for words/kanji. |
| `glyph` | `string` | Yes |  |
| `romaji` | `string` | Yes | Expected reading; lowercase Hepburn, exact case-insensitive match. |
| `weight` | `integer` | No | Optional author priority override. Fixed-point ×10000 (e.g. 1.8 -> 18000); lexicons have no float type. App scales at the record edge (see README). |
| `confusableWith` | `array` | No | ROMAJI (not glyphs) of same-script confusers; cold-start distractor seed. |

### `at.kotoba.lesson.pack`

**Type**: `record`

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

**Key**: `tid`

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `meta` | `unknown` | No | Pack-level open extension; UI ignores, round-trips. |
| `items` | `array` | Yes |  |
| `phase` | `string` | No | Open. kana \| vocab \| grammar. |
| `title` | `string` | Yes |  |
| `script` | `array` | No | Declared scripts; drives chips + Focus. Derived from item types if omitted. |
| `defaults` | `ref` → `#defaults` | No |  |
| `createdAt` | `string` | No | ISO 8601. NOTE: the app currently stamps a date-only string (YYYY-MM-DD), not a datetime — left unformatted here pending reconciliation (see README). |
| `rationale` | `string` | No |  |

### `at.kotoba.lesson.pack#defaults`

**Type**: `object`

Pack-level drill defaults (SPEC §4). Open additional keys round-trip via the pack `meta`.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `tapToTypeBox` | `integer` | No | Leitner box at/above which a glyph may graduate tap -> type. |
| `katakanaMultiplier` | `integer` | No | Queue weight multiplier for katakana. Fixed-point ×10000 (e.g. 1.5 -> 15000); no float type. |

## Raw Schema

```json
{
  "id": "at.kotoba.lesson.pack",
  "defs": {
    "item": {
      "type": "object",
      "required": [
        "glyph",
        "romaji",
        "type"
      ],
      "properties": {
        "row": {
          "type": "string",
          "description": "Gojuon row label, single kana only."
        },
        "meta": {
          "type": "unknown",
          "description": "Item-level open extension; UI ignores, round-trips."
        },
        "type": {
          "type": "string",
          "description": "Open. hiragana | katakana | kanji | word."
        },
        "gloss": {
          "type": "string",
          "description": "English meaning; recommended for words/kanji."
        },
        "glyph": {
          "type": "string"
        },
        "romaji": {
          "type": "string",
          "description": "Expected reading; lowercase Hepburn, exact case-insensitive match."
        },
        "weight": {
          "type": "integer",
          "description": "Optional author priority override. Fixed-point ×10000 (e.g. 1.8 -> 18000); lexicons have no float type. App scales at the record edge (see README)."
        },
        "confusableWith": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "ROMAJI (not glyphs) of same-script confusers; cold-start distractor seed."
        }
      },
      "description": "A card. Core: glyph/romaji/type. `glyph` is 1+ chars (single kana, word, or kanji)."
    },
    "main": {
      "key": "tid",
      "type": "record",
      "record": {
        "type": "object",
        "required": [
          "title",
          "items"
        ],
        "properties": {
          "meta": {
            "type": "unknown",
            "description": "Pack-level open extension; UI ignores, round-trips."
          },
          "items": {
            "type": "array",
            "items": {
              "ref": "#item",
              "type": "ref"
            }
          },
          "phase": {
            "type": "string",
            "description": "Open. kana | vocab | grammar."
          },
          "title": {
            "type": "string"
          },
          "script": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Declared scripts; drives chips + Focus. Derived from item types if omitted."
          },
          "defaults": {
            "ref": "#defaults",
            "type": "ref"
          },
          "createdAt": {
            "type": "string",
            "description": "ISO 8601. NOTE: the app currently stamps a date-only string (YYYY-MM-DD), not a datetime — left unformatted here pending reconciliation (see README)."
          },
          "rationale": {
            "type": "string"
          }
        }
      },
      "description": "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)."
    },
    "defaults": {
      "type": "object",
      "properties": {
        "tapToTypeBox": {
          "type": "integer",
          "maximum": 5,
          "minimum": 1,
          "description": "Leitner box at/above which a glyph may graduate tap -> type."
        },
        "katakanaMultiplier": {
          "type": "integer",
          "description": "Queue weight multiplier for katakana. Fixed-point ×10000 (e.g. 1.5 -> 15000); no float type."
        }
      },
      "description": "Pack-level drill defaults (SPEC §4). Open additional keys round-trip via the pack `meta`."
    }
  },
  "$type": "com.atproto.lexicon.schema",
  "lexicon": 1
}
```
