From 8cd2667b820a5f9c3bc800cd08c4b3605c9c4cfe Mon Sep 17 00:00:00 2001 From: Asterios Raptis Date: Thu, 1 Oct 2026 11:56:07 +0200 Subject: [PATCH] docs: describe the engine-owned rules and the engine-gated generator The template's #92 moved the content rules to the engine; its wave carried the template-owned files only, so this repository's README and GETTING-STARTED still named the dropped distractor requirement, the validator as the rule checker, PyYAML as its only dependency and an optional engine gate after generation. Co-Authored-By: Claude Opus 5.5 (1M context) --- README.md | 28 ++++++++++++++-------------- docs/GETTING-STARTED.md | 33 +++++++++++++++++++++------------ 2 files changed, 35 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index ce47d5b..409052a 100644 --- a/README.md +++ b/README.md @@ -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//`, 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//`, 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//-/lessons/`, register it in the set diff --git a/docs/GETTING-STARTED.md b/docs/GETTING-STARTED.md index 1fce9be..8bd2409 100644 --- a/docs/GETTING-STARTED.md +++ b/docs/GETTING-STARTED.md @@ -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 @@ -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) @@ -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 @@ -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/).