# Classics Reader — Latin readings

Context for Claude when preparing a Latin reading for the Classics Reader.

Adapted from the CLAUDE.md of the LAT30 course site this reader grew out of.
That site organized everything around the **quiz** it would be tested on. This
one does not: **the unit is a reading — one chapter, one file.** A reading is
complete on its own, stands on its own, and is added without reference to
anything else.

This is the Latin twin of the Greek spec beside it. Same engine, same workflow,
same file layout — the differences are Latin's, not the project's.

## What this is
An interactive reader for whole Latin texts. Latin on the left, a literal English
translation on the right, aligned clause by clause; every word is a clickable
token carrying lemma, part of speech, parse, gloss and a syntax note. From that
same token data the reader derives a parse trainer, form drills, practice
questions and Anki vocabulary decks.

Readings are addressed as `work / book / chapter`. A short standalone passage is
simply chapter *n* of book 1 of its work; a real text uses its own book and
chapter numbers.

## The task — when the user uploads Latin
Two things happen for every new reading. Do both.

1. **Write the chapter file** — one JSON object at
   `public/data/<work>/<book>/<chapter>.json` (schema below).
2. **File it in the manifest** — one entry appended to that work's `chapters`
   array in `public/data/manifest.json`, in reading order, and bump the book's
   chapter count.

That is the whole job. There is no quiz to assign it to, no deck to build and no
question bank to write — see "What you do not write" below.

## Chapter object schema
```js
{
  work: "lat30",                       // work id; matches the folder under data/
  book: 1,
  chapter: 1,                          // position in the book; the URL is
                                       // /read/<work>/<book>/<chapter>
  slug: "aen4-1-30",                   // unique, no spaces — stable id for the reading
  title: "Aeneid 4.1–30",              // "<Work> <book>.<lines>"
  citation: "Vergil, Aeneid 4.1–30 — Dido confesses her love to Anna",
  defaultSrc: "human-verified",        // provenance of the analysis; see below
  segments: [                          // each segment = one aligned Latin↔English row
    {
      lines: "1–2",                    // verse line/range, or a prose section ("1.3").
                                       // Verse: label EVERY segment. Prose: label the
                                       // first segment of each section; the engine
                                       // carries the label forward.
      translation: "literal English for this chunk",
      greek: [                         // one token per word, in order. NOTE the field
                                       // is `greek` in Latin chapters too: it predates
                                       // the reader having a second language and means
                                       // "the source-language tokens" either way.
        { w:"regina",                  // the Latin word as it appears in the text
          lemma:"rēgīna, -ae, f.",
          pos:"noun",
          parse:"nom. sg. fem.",
          gloss:"queen",
          note:"subject of the sentence; Dido is not named until line 9" },
        { w:".", punct:true }          // punctuation: renders but is NOT clickable
      ]
    }
  ]
}
```

## Manifest entry
`public/data/manifest.json` is what the contents page reads. Each work carries its
own `chapters` array:

```js
{ book: 1,
  chapter: 1,
  slug: "aen4-1-30",
  title: "Aeneid 4.1–30",
  segments: 30,                        // segments in the file
  tokens: 210,                         // non-punctuation tokens
  bytes: 41022 }                       // the file's own size
```

The three numbers are just the file's own figures; they drive the word counts on
the contents page. A new work needs an object of its own with `id`, `title`,
`author`, an optional one-line `note`, `defaultSrc`, and a `books` array.

## Provenance — say where the analysis came from
`defaultSrc` records the provenance of a chapter's analysis, and any single token
may override it with its own `src`. It shows in the word panel as a badge.

- `treebank` — from a gold-standard dependency treebank
- `morpheus+model` — an analyser licensed the parse; a model chose among the options
- `model-only` — no analyser coverage (proper nouns, corruption)
- `human-verified` — a person checked it

Be honest with this field. The whole point of carrying it is that generated
analysis must never quietly present itself as checked analysis. If you parsed a
reading and nobody has read it back against the text, it is not `human-verified`.

## Conventions
- **Layout:** Latin on the LEFT, literal English on the RIGHT, aligned per segment.
- **Segment size:** clause/sentence-sized. This matters more than it looks: the
  segment is the unit the practice window is cut out of, and the unit a citation
  points at. Aim for ~7–12 Latin words. Never one giant segment per chapter.
- **Translation style:** **as literal as possible while still reading sensibly** —
  faithful to case, tense, and word force, but not so wooden it stops making sense.
  Not smooth idiomatic paraphrase. (Practice uses these as its model translation
  answers, so they must be defensible word by word.) In verse, do NOT reorder into
  prose order silently — if the word order is doing something, say so in a `note`.
- **Macrons:** the `w` field is the text as the edition prints it (normally without
  macrons). The `lemma` field DOES carry macrons — it is what the vocab deck drills.
  Be consistent: the deck's Front is the lemma string character for character.
- **Lemma format:**
  - noun — `rēgīna, -ae, f.` (nom., gen., gender)
  - adjective — `magnus, -a, -um` / `fortis, -e` / `ingēns, -entis`
  - verb — all four principal parts: `amō, amāre, amāvī, amātum`
    (deponent: three — `sequor, sequī, secūtus sum`)
- **Parsing style:** spell it out in full — "perfect active indicative, 3rd singular",
  not "perf. act. ind. 3 sg." Nominals may abbreviate case/number/gender in the usual
  way ("abl. sg. fem."), which is what the parse trainer expects.
  - Participles get both halves: "perfect passive participle, feminine ablative singular".
  - Deponents are labelled **deponent**, not passive: "perfect deponent indicative,
    3rd singular". The parse trainer offers deponent as its own voice.
  - Gerund, gerundive, and supine are moods as far as the parser is concerned —
    write "gerundive, neuter nominative singular", "gerund, genitive singular",
    "supine, accusative".
- **Every Latin word** is its own clickable token with lemma / pos / parse / gloss,
  plus a syntax `note` where useful. The `note` is not decoration: practice reuses
  it as the explanation for auto-generated parsing questions, so write it as a
  reason, not a label. Word order in verse is worth a note when it is doing work —
  hyperbaton, golden lines, enjambment, framing.
- **Line weight:** the engine scores a verse segment by its line range and a prose
  segment at ~7 Latin words to the line, so a "20-line window" means the same amount
  of reading in Vergil and in Cicero. Label `lines` honestly and this takes care of
  itself.

## What you do not write
The reader derives these from the token data. Do not hand-write them.

- **Practice questions** — translation, parsing and vocabulary questions are
  generated, and the answer key *is* the token's lemma/parse/gloss and the
  segment's translation. They cannot drift out of sync with the text, and they
  come free with a well-parsed reading.
- **Vocabulary decks** — the Anki deck is built from the tokens. General
  vocabulary is included; particles, prepositions, pronouns, conjunctions and
  interjections are skipped. The deck nests under its book, so a whole book can be
  drilled at once, and Latin decks live in their own tree, separate from Greek.

The LAT30 site also had hand-written "what construction is this, and why"
questions — ablative absolute, indirect statement, purpose and result clauses,
`cum`-clauses, the gerundive of obligation, and the rest. Those are dropped here:
they do not scale to a whole text. If you want that kind of explanation, put it in
a token's `note`, where it is attached to the word it is about and costs nothing
to maintain.

## Checking your work
Two checks catch nearly everything that matters.

1. **The tokens must reconstruct the text.** Concatenate every `w` in order and
   compare against the source. This catches dropped words, invented words,
   reordering and skipped lines — the failures that would poison every drill,
   question and deck built on top of the reading.
2. **The morphology must be bounded.** A model asked to parse freely produces
   confident wrong answers a student has no way to catch. Constrain it to the
   analyses the surface form actually licenses and let it choose among them. A
   parse outside that set is a bug, not a judgement call.

Careful with shell dedup checks on macronised Latin: macOS can hand you the same
word in two Unicode normalisations (precomposed `ē` versus `e` plus a combining
macron), and a UTF-8 locale may also collate `e` and `ē` as equal. Use `LC_ALL=C`,
or check in Python.

Then open `/read/<work>/<book>/<chapter>` and read it.
