Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -285,20 +285,20 @@ python3 scripts/generate_exercises.py \
### What happens, and what you still owe

The script pins the exact lesson-schema JSON in the prompt, parses the
model's reply, and runs it through `validate_content.py`. If validation
fails, the errors go back to the model and it retries (up to `--retries`);
a draft that never validates is discarded, not written. A valid draft
lands in `generated/<set-id>/`, never directly in `sets/`.

Two gates remain after generation, neither of them automatic:

1. **Engine semantic gate** (cloze `___` markers equal the blanks,
`card_ids` integrity, multiselect disjointness). It runs when the
pinned `learn-content-engine` is installed, otherwise it is deferred to
CI. The plain validator does not cover it.
2. **Native-speaker review** for a language you do not speak natively. No
validator catches an unnatural phrasing or a wrong romanization.
Machine-generated, then human-verified, is the only trustworthy order.
model's reply, and checks it twice: against the mirrored schema, then
through the pinned engine (`scripts/engine_check.mjs`: the semantic rules
such as cloze `___` markers equal to the blanks, `card_ids` integrity and
multiselect disjointness, plus the quality minimums). If a check fails, the
errors go back to the model and it retries (up to `--retries`); a draft
that never passes is discarded, not written. A passing draft lands in
`generated/<set-id>/`, never directly in `sets/`. Without the installed
engine the generator stops before it calls the model (`make generate`
installs it, and so does `make lint`).

One gate remains after generation, and it is not automatic: the
**native-speaker review** for a language you do not speak natively. No
validator catches an unnatural phrasing or a wrong romanization.
Machine-generated, then human-verified, is the only trustworthy order.

When a draft is good, move it from `generated/` into your set under
`sets/<source>/<target>-<level>/lessons/`, register it in the set
Expand Down
33 changes: 21 additions & 12 deletions docs/GETTING-STARTED.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ For the full field reference, see [LESSON-FORMAT.md](LESSON-FORMAT.md).
You need:

- **Git** and a **GitHub account**.
- **`make`** and **Python 3**. That is all: the first `make validate`
creates a local environment and installs the validator's dependencies
(`pyyaml`, `jsonschema`) for you. No manual `pip`, no virtualenv.
- **`make`** and **Python 3**. The first `make validate` creates a local
environment and installs the validator's dependencies
(`requirements.txt`) for you. No manual `pip`, no virtualenv.
- **Node.js and npm** for the engine gate (`make lint`) and the AI
generator. The first run installs the engine release this repository
pins.
- A text editor.

> No `make` (e.g. Windows without WSL)? Either create a virtualenv
Expand Down Expand Up @@ -56,11 +59,16 @@ Open `sets/en/my-set/lessons/01-greetings.json` and change:
least two of the six types (matching, free_text, cloze, word_tiles,
picture_choice, multiple_choice).

Keep these or the validator will complain:
Keep these or the engine gate will complain:

- `free_text` needs **≥ 2 accepts** and at least one **distractor**.
- `matching` needs **≥ 3 pairs**.
- `picture_choice` needs **distractors** and exactly one `is_correct: "true"`.
- `free_text` needs **≥ 2 accepts**.
- `matching` needs **≥ 3 pairs** (with `from_cards`, the cards it names count).
- `picture_choice` needs exactly one `is_correct: "true"`.

An introduction or a part divider that only leads over declares
`"purpose": "bridge"` (no exercise minimum), a check in one exercise type
declares `"purpose": "quiz"` (no exercise-type minimum); see
[LESSON-FORMAT.md](LESSON-FORMAT.md#validation-rules-the-quality-gate).

## 3. Register the lesson (2 min)

Expand Down Expand Up @@ -105,12 +113,13 @@ You want:
All N set(s) passed validation.
```

If it fails, the message names the lesson and the rule (e.g.
`free_text '…' needs distractors`). Fix and re-run.
If it fails, the message names the lesson and the problem (e.g. a set path
that does not match its language and level). Fix and re-run.

**Before you push**, also run the engine gate locally: the same semantic
rules (stable rule ids such as `E-CARD-REF`, cloze markers, multiple-choice
rules) that CI enforces in the `Engine conformance` workflow:
rules) and quality minimums that CI enforces in the `Engine conformance`
workflow:

```bash
make lint
Expand Down Expand Up @@ -154,8 +163,8 @@ make generate ARGS="--topic 'Ordering food in a café' --target-lang fr --source

Drafts land in `generated/` (never in `sets/`); you review them, then move
them into a set and re-run `make validate`. Full flag table, the direct
(non-make) invocation, and the two remaining gates (engine semantics,
native-speaker review) are in the README's
(non-make) invocation, and the gate that remains (native-speaker review)
are in the README's
[Generate exercises with AI](../README.md#generate-exercises-with-ai-optional)
section. The generator is language-focused; for a knowledge set
(source == target) hand-author from [`templates/knowledge/`](../templates/knowledge/).
Loading