From a85e34ff42680041a40018810f56a48da24fcfac Mon Sep 17 00:00:00 2001 From: Asterios Raptis Date: Fri, 24 Jul 2026 10:34:37 +0200 Subject: [PATCH] docs: replace real em/en dashes in the repo prose; fix stale claims Second half of the engine#80 rule (no real AND no faked dashes): the faked-dash sweep landed earlier, this replaces the real em/en dashes in the repo's own markdown prose by context (colon for definitions and explanations, comma for appositions, parentheses for asides, sentence break for independent thoughts). Verbatim-quoted learner content and manifest-recorded set titles keep their dashes (content, not prose). Stale factual claims found during the same audit are fixed where this repo carries them: removed domain_label mentions (dropped repo-wide in content#144), corrected the dog-training domain claim, dropped out-of-date '(currently 0.12.x)' engine-version parentheticals, and documented the visibility index field (official repo). Co-Authored-By: Claude Fable 5 --- README.md | 35 +++++++++++++++++------------------ docs/GETTING-STARTED.md | 6 +++--- docs/LESSON-FORMAT.md | 10 +++++----- generated/README.md | 4 ++-- schema/README.md | 16 ++++++++-------- templates/README.md | 6 +++--- 6 files changed, 38 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 0d42b36..0e87397 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,7 @@ content repository for **Programmierung** (programming): a Git repository of plain lesson files that the app loads directly and no vendor can lock away. -It ships three German-language knowledge sets (domain `programming`, -`domain_label` Programmierung) in ascending difficulty: a Python +It ships three German-language knowledge sets (domain `programming`) in ascending difficulty: a Python beginners course and a two-part React series. This repository was created from [adaptive-learner-content-template](https://github.com/astrapi69/adaptive-learner-content-template), @@ -28,7 +27,7 @@ described below. Drei Sets, 28 Lektionen, Quell- und Zielsprache Deutsch. Empfohlene Reihenfolge: -### Teil 1 — `sets/de/python-basics` (A1, 15 Lektionen) +### Teil 1: `sets/de/python-basics` (A1, 15 Lektionen) Einführung in die Programmierung mit Python: von `print()` und Variablen über Strings, Listen, Bedingungen und Schleifen bis zu Funktionen, @@ -40,7 +39,7 @@ mit lauffähigen Code-Beispielen und erwarteter Ausgabe. | 01 | `01-erste-schritte.json` | Erste Schritte mit Python | | 02 | `02-variablen-und-datentypen.json` | Variablen und Datentypen | | 03 | `03-zahlen-und-operatoren.json` | Zahlen und Operatoren | -| 04 | `04-strings.json` | Strings — mit Text arbeiten | +| 04 | `04-strings.json` | Strings: mit Text arbeiten | | 05 | `05-listen.json` | Listen (Lists) | | 06 | `06-bedingungen.json` | Bedingungen (if / elif / else) | | 07 | `07-schleifen.json` | Schleifen (for & while) | @@ -53,7 +52,7 @@ mit lauffähigen Code-Beispielen und erwarteter Ausgabe. | 14 | `14-comprehensions.json` | List Comprehensions | | 15 | `15-wiederholung.json` | Wiederholung und Festigung | -### Teil 2 — `sets/de/react-grundlagen` (A2, 5 Lektionen) +### Teil 2: `sets/de/react-grundlagen` (A2, 5 Lektionen) | # | Lesson | Titel | |---|--------|-------| @@ -63,7 +62,7 @@ mit lauffähigen Code-Beispielen und erwarteter Ausgabe. | 04 | `04-state-usestate.json` | State mit useState: Re-Render statt direkter Mutation | | 05 | `05-events-und-grundprinzipien.json` | Events, Hooks & Grundprinzipien: Re-Render und Komposition | -### Teil 3 — `sets/de/react-fortgeschritten` (B1, 8 Lektionen) +### Teil 3: `sets/de/react-fortgeschritten` (B1, 8 Lektionen) | # | Lesson | Titel | |---|--------|-------| @@ -78,19 +77,19 @@ mit lauffähigen Code-Beispielen und erwarteter Ausgabe. ## What's inside -- `manifest.yaml` — the root manifest listing the sets. +- `manifest.yaml`: the root manifest listing the sets. - `sets/de/python-basics/`, `sets/de/react-grundlagen/`, - `sets/de/react-fortgeschritten/` — the lesson sets. -- `schema/` — the pinned [`learn-content-engine`](https://github.com/astrapi69/learn-content-engine) + `sets/de/react-fortgeschritten/`: the lesson sets. +- `schema/`: the pinned [`learn-content-engine`](https://github.com/astrapi69/learn-content-engine) schema mirror; [`engine-version.txt`](schema/engine-version.txt) holds the pinned engine version and is the source of truth. This is what the content - is validated against — independent of the app. -- `templates/` — starting-point lessons per domain (language / programming / knowledge). -- `scripts/validate_content.py` — the local validator. -- `scripts/generate_exercises.py` — an optional BYOK AI exercise generator. -- `generated/` — staging area for AI drafts (never shipped directly). -- `.github/workflows/` — CI that validates every push/PR against the pinned engine. -- `docs/` — [GETTING-STARTED.md](docs/GETTING-STARTED.md) and a local + is validated against, independent of the app. +- `templates/`: starting-point lessons per domain (language / programming / knowledge). +- `scripts/validate_content.py`: the local validator. +- `scripts/generate_exercises.py`: an optional BYOK AI exercise generator. +- `generated/`: staging area for AI drafts (never shipped directly). +- `.github/workflows/`: CI that validates every push/PR against the pinned engine. +- `docs/`: [GETTING-STARTED.md](docs/GETTING-STARTED.md) and a local [LESSON-FORMAT.md](docs/LESSON-FORMAT.md). The **canonical, test-validated** format reference is the engine's [`docs/lesson-format.md`](https://github.com/astrapi69/learn-content-engine/blob/main/docs/lesson-format.md). @@ -116,7 +115,7 @@ and npm) and checks every lesson and manifest with the engine's rule ids (`E-CARD-REF` & co.). `make lint-warnings` additionally prints the engine gate's warnings (`W-*`). No `make` (e.g. Windows without WSL)? Two options: run the validator in a -virtualenv yourself — +virtualenv yourself: ```bash python3 -m venv .venv && . .venv/bin/activate # Windows: .venv\Scripts\activate @@ -124,7 +123,7 @@ pip install -r requirements.txt python3 scripts/validate_content.py ``` -— or just commit and let the GitHub Actions CI validate (it runs the same +Or just commit and let the GitHub Actions CI validate (it runs the same checks). Installing the deps globally with a bare `pip install` fails on modern Debian/Ubuntu/macOS (PEP 668, "externally-managed-environment"); the virtualenv above is why. diff --git a/docs/GETTING-STARTED.md b/docs/GETTING-STARTED.md index 547441e..1fce9be 100644 --- a/docs/GETTING-STARTED.md +++ b/docs/GETTING-STARTED.md @@ -1,4 +1,4 @@ -# Getting started — your first lesson in 10 minutes +# Getting started: your first lesson in 10 minutes This walkthrough takes you from zero to a validated lesson. You'll copy a template, edit it, register it, and run the validator. @@ -18,12 +18,12 @@ You need: > No `make` (e.g. Windows without WSL)? Either create a virtualenv > yourself (`python3 -m venv .venv`, activate it, > `pip install -r requirements.txt`), or skip local validation and let the -> GitHub Actions CI check your commit — it runs the same validator. A bare +> GitHub Actions CI check your commit: it runs the same validator. A bare > `pip install` fails on modern systems (PEP 668). ### Start your own content repository -Create your repository from this template — **“Use this template” → Create +Create your repository from this template: **“Use this template” → Create a new repository** (not *Fork*), then clone your new repo: > → **Use diff --git a/docs/LESSON-FORMAT.md b/docs/LESSON-FORMAT.md index e2fb651..bc5f090 100644 --- a/docs/LESSON-FORMAT.md +++ b/docs/LESSON-FORMAT.md @@ -1,4 +1,4 @@ -# Lesson format — local summary +# Lesson format: local summary > **The canonical, test-validated format reference is the engine's** > **[`docs/lesson-format.md`](https://github.com/astrapi69/learn-content-engine/blob/main/docs/lesson-format.md)** @@ -13,7 +13,7 @@ This is a field-by-field summary of the lesson format used by this repository. Lessons that follow it pass `scripts/validate_content.py` and load in the Adaptive Learner app. -The lesson format is **one JSON file per lesson** — this is what the app loads +The lesson format is **one JSON file per lesson**: this is what the app loads and the validator checks. It is summarised below. New to this? Start with [GETTING-STARTED.md](GETTING-STARTED.md) and copy a @@ -32,7 +32,7 @@ manifest.yaml # root: lists every set ``` - **Language sets** live at `sets//-/` - (e.g. `sets/en/es-a1/` — Spanish for English speakers, level A1). + (e.g. `sets/en/es-a1/`: Spanish for English speakers, level A1). - **Non-language sets** (e.g. psychology, programming) use a topic folder name (e.g. `sets/de/psych-intro/`), because material and explanation share one language. @@ -123,8 +123,8 @@ The inner `exercise` object's `type` picks one of the six exercise types below. Most carry `card_ids` (the cards they draw on) and a `direction`. **`direction`** (productive vs receptive): -- `source_to_target` — learner produces the target language (harder). -- `target_to_source` — learner recognises/translates into the source (easier). +- `source_to_target`: learner produces the target language (harder). +- `target_to_source`: learner recognises/translates into the source (easier). ## The six exercise types diff --git a/generated/README.md b/generated/README.md index dea446c..f4f42a6 100644 --- a/generated/README.md +++ b/generated/README.md @@ -1,4 +1,4 @@ -# generated/ — Staging-Bereich für KI-Entwürfe +# generated/: Staging-Bereich für KI-Entwürfe `scripts/generate_exercises.py` schreibt jede generierte Lektion HIERHER, niemals direkt in einen ausgelieferten `sets/`-Baum. Das ist die @@ -11,7 +11,7 @@ Ablauf: `generated//.json` an (nur nachdem der Entwurf den Struktur- + Qualitäts-Gate von `validate_content.py` bestanden hat). 2. Sichten: Lies die Lektion. Für eine Sprache, die du nicht muttersprachlich - sprichst, hol ein Muttersprachler-Review ein — kein Validator erkennt + sprichst, hol ein Muttersprachler-Review ein: kein Validator erkennt eine unnatürliche Formulierung oder eine falsche Umschrift. 3. Einsortieren: Verschiebe die Datei in dein Set unter `sets///lessons/`, trage sie im Set-Manifest ein diff --git a/schema/README.md b/schema/README.md index d0f3572..371dc25 100644 --- a/schema/README.md +++ b/schema/README.md @@ -1,4 +1,4 @@ -# Schema (mirror — do not edit here) +# Schema (mirror, do not edit here) **Mirror of the `learn-content-engine` `schema/`**, pinned to the version in [`engine-version.txt`](engine-version.txt) (source of truth chain: @@ -19,17 +19,17 @@ together in one deliberate PR, so the pinned version lives in exactly one place |------|-----------------------------|------------------| | `lesson.schema.json` | `package/schema/lesson.schema.json` | `scripts/validate_content.py` (structural validation via `jsonschema`), `tests/test_shape_parity.py` | | `content-manifest.schema.json` | `package/schema/content-manifest.schema.json` | vendored for IDE autocomplete / third-party manifest validation; CI validates manifests with the engine itself (`engine-validate.yml`) | -| `quality-rules.json` | `package/schema/quality-rules.json` (engine ≥ 0.4.0 — locally owned before that) | `scripts/validate_content.py` (quality minimums: `minExercisesPerLesson`, `minExerciseTypes`, `minFreeTextAccepts`, `minMatchingPairs`, `minTheorySteps`) | -| `engine-version.txt` | — (the pin itself) | `scripts/check_schema_drift.py`, `.github/workflows/engine-validate.yml` | +| `quality-rules.json` | `package/schema/quality-rules.json` (engine ≥ 0.4.0, locally owned before that) | `scripts/validate_content.py` (quality minimums: `minExercisesPerLesson`, `minExerciseTypes`, `minFreeTextAccepts`, `minMatchingPairs`, `minTheorySteps`) | +| `engine-version.txt` | - (the pin itself) | `scripts/check_schema_drift.py`, `.github/workflows/engine-validate.yml` | -`lesson.schema.json` is a self-contained JSON Schema (Draft 2020-12) — its +`lesson.schema.json` is a self-contained JSON Schema (Draft 2020-12). Its `$id`, `$schema` and `x-schema-version` make it usable for IDE autocomplete (reference it from a lesson `.json` via `"$schema"`) and for `jsonschema`/`ajv` validation. ## Locally owned (NOT part of the engine mirror) -* `../tests/fixtures/lesson-shape-parity.json` — the shape-parity fixture +* `../tests/fixtures/lesson-shape-parity.json`: the shape-parity fixture snapshot (see `tests/test_shape_parity.py`). The cross-repo parity guarantee is closed by the app's own app-vs-engine parity test plus this repo's engine-pinned drift gate, so the fixture no longer needs to be @@ -40,12 +40,12 @@ validation. `scripts/check_schema_drift.py` (run in CI by `.github/workflows/schema-drift.yml`) downloads the **npm tarball of the pinned engine release** at CI time and compares it byte-for-byte against -this mirror. The npm tarball — not a git tag — is the comparison source +this mirror. The npm tarball (not a git tag) is the comparison source because a published npm version is immutable (the registry refuses re-publishing a version, git tags can be moved or deleted), it is exactly the artefact validator consumers install via `npm ci learn-content-engine@`, and it needs a single anonymous HTTPS -GET — no GitHub token, still Python-stdlib-only. +GET: no GitHub token, still Python-stdlib-only. The mirror stays **vendored** so validation works offline: only the drift CHECK itself needs network. @@ -65,6 +65,6 @@ after an accidental hand-edit). `.github/workflows/engine-validate.yml` additionally runs the engine's own `validateLesson()` / `validateManifest()` (at the pinned version) over the -whole repo content — the semantic rules (cloze blanks == markers, +whole repo content: the semantic rules (cloze blanks == markers, referential integrity, multiselect disjointness, picture exactly-one-correct) that a JSON Schema cannot express. Gate: zero errors. diff --git a/templates/README.md b/templates/README.md index 6f749bd..f55e528 100644 --- a/templates/README.md +++ b/templates/README.md @@ -2,7 +2,7 @@ Copy-and-edit starting points for new lessons, one per content **domain**. -A lesson is a **single JSON file** — that is the lesson format. Pick the +A lesson is a **single JSON file**: that is the lesson format. Pick the template for your domain and copy it. | Template | Domain | Use it for | @@ -19,7 +19,7 @@ template for your domain and copy it. 3. **Replace** the placeholder cards, theory and exercises with your content. 4. **Register** the file in your set's `manifest.yaml` (`metadata.lessons`) and make sure the set is listed in the root `manifest.yaml`. -5. **Validate**: `python scripts/validate_content.py` — it must print +5. **Validate**: `python scripts/validate_content.py`, it must print `All N set(s) passed validation.` > JSON has no comments, so the field-by-field explanations live in @@ -35,7 +35,7 @@ with distractors. Keep those minimums when you edit. ## Domain differences at a glance - **language**: `domain: language`, `target_language` **and** `source_language` - differ, `level` is a CEFR band (A1–C2). Matching/free-text use a + differ, `level` is a CEFR band (A1-C2). Matching/free-text use a translation context (target ↔ source). - **knowledge**: `domain: psychology` (or another non-language domain), `source_language == target_language`, no separate target. Matching/free-text