From 019a9bfd41dda8f6f5eefb552cd8a1e3dbb519c9 Mon Sep 17 00:00:00 2001 From: ttbombadil Date: Sun, 27 Sep 2026 19:46:10 +0200 Subject: [PATCH 1/5] fix: narrow variables tutor topic activation --- tutor/manifest.yaml | 2 +- tutor/topics/variables-and-serial.yaml | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/tutor/manifest.yaml b/tutor/manifest.yaml index 1313bc6..00a2369 100644 --- a/tutor/manifest.yaml +++ b/tutor/manifest.yaml @@ -3,7 +3,7 @@ defaultStrategy: precision-policy topics: - id: variables-and-serial path: tutor/topics/variables-and-serial.yaml - sha256: 84fc5f3de8722fc4c5d1b47da7bc2e262c82fd20b41d33f14aa6a244b15ca1d2 + sha256: 120e5f9604b82ddd006f712a18bf6ef865de736e0071a432f4396170de998f49 - id: long-values path: tutor/topics/long-values.yaml sha256: 1cc3c7ab861443503f1f47acb2863157ae92a2489cbaa55a2b30516c89b96859 diff --git a/tutor/topics/variables-and-serial.yaml b/tutor/topics/variables-and-serial.yaml index 640901a..f6d351e 100644 --- a/tutor/topics/variables-and-serial.yaml +++ b/tutor/topics/variables-and-serial.yaml @@ -4,8 +4,6 @@ title: Variablen, Literale und Serial-Ausgabe locale: de-DE activation: any: - - fact: type-used - values: [int] - fact: serial-call values: [print] concepts: @@ -56,7 +54,7 @@ questions: requires: - fact: type-used values: [int] - text: Welchen Wert verwendet der Sketch an der betrachteten Integer-Variablen? + text: Welche Rolle spielt der Integer-Datentyp im aktuellen Sketch? - id: serial-output-concept concept: serial-output indicator: explains-serial-output From 71c4e07a099a3e8a4bc5b2d0e67d3ac3ae5d29cb Mon Sep 17 00:00:00 2001 From: ttbombadil Date: Sun, 27 Sep 2026 20:44:57 +0200 Subject: [PATCH 2/5] test: add tutor content quality cases --- tutor/manifest.yaml | 4 ++-- tutor/quality-cases.yaml | 12 ++++++++++++ tutor/topics/long-values.yaml | 18 ++++++++++++++++++ tutor/topics/variables-and-serial.yaml | 20 ++++++++++++++++++++ 4 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 tutor/quality-cases.yaml diff --git a/tutor/manifest.yaml b/tutor/manifest.yaml index 00a2369..9dc0dcc 100644 --- a/tutor/manifest.yaml +++ b/tutor/manifest.yaml @@ -3,10 +3,10 @@ defaultStrategy: precision-policy topics: - id: variables-and-serial path: tutor/topics/variables-and-serial.yaml - sha256: 120e5f9604b82ddd006f712a18bf6ef865de736e0071a432f4396170de998f49 + sha256: f80f62a304e4183f4102672f0d9af4e1f8dbe5823a09bfabeba999a65f8b5c6b - id: long-values path: tutor/topics/long-values.yaml - sha256: 1cc3c7ab861443503f1f47acb2863157ae92a2489cbaa55a2b30516c89b96859 + sha256: d0c801fca7749d6b91fd743a386077ad41fd5bef002df6e6330eaff5c713b4f5 strategies: - id: precision-policy path: tutor/strategies/precision-policy.yaml diff --git a/tutor/quality-cases.yaml b/tutor/quality-cases.yaml new file mode 100644 index 0000000..98ce857 --- /dev/null +++ b/tutor/quality-cases.yaml @@ -0,0 +1,12 @@ +schemaVersion: 1 +cases: + - id: variables-serial-positive + example: it01-01-variable-speichern + expectedTopics: [variables-and-serial] + forbiddenTopics: [long-values] + - id: pwm-does-not-activate-variables + example: it04-03-pwm-ausgang + forbiddenTopics: [variables-and-serial, long-values] + - id: long-values-positive + example: it03-05-millis + expectedTopics: [long-values] diff --git a/tutor/topics/long-values.yaml b/tutor/topics/long-values.yaml index 7db6eee..d723176 100644 --- a/tutor/topics/long-values.yaml +++ b/tutor/topics/long-values.yaml @@ -64,6 +64,24 @@ questions: - fact: type-used values: [long] text: Warum passt der Datentyp long zur im Sketch gespeicherten Information? + - id: long-value-prediction + concept: execution-structure + indicator: identifies-long-value + kind: prediction + difficulty: [20, 80] + requires: + - fact: type-used + values: [long] + text: Wie erwartest du, dass sich der gespeicherte long-Wert beim nächsten Schleifendurchlauf verändert? + - id: long-value-transfer + concept: timing-interval + indicator: explains-long-usage + kind: transfer + difficulty: [20, 80] + requires: + - fact: type-used + values: [long] + text: Welche weitere zeitbezogene Information könntest du im aktuellen Sketch mit einem long-Wert erfassen, ohne den vollständigen Code zu entwerfen? scaffolds: - id: long-value-scaffold forConcept: timing-interval diff --git a/tutor/topics/variables-and-serial.yaml b/tutor/topics/variables-and-serial.yaml index f6d351e..d3487e8 100644 --- a/tutor/topics/variables-and-serial.yaml +++ b/tutor/topics/variables-and-serial.yaml @@ -64,6 +64,26 @@ questions: - fact: serial-call values: [print] text: Welche Rolle hat der Serial-Ausgabeaufruf in diesem Sketch? + - id: variable-output-application + concept: variable-values + indicator: relates-value-to-use + kind: application + difficulty: [20, 80] + requires: + - fact: type-used + values: [int] + - fact: serial-call + values: [print] + text: Wie hängt der gespeicherte Integerwert mit der sichtbaren seriellen Ausgabe im aktuellen Sketch zusammen? + - id: serial-output-transfer + concept: serial-output + indicator: explains-serial-output + kind: transfer + difficulty: [20, 80] + requires: + - fact: serial-call + values: [print] + text: Welche gezielte Wertänderung im aktuellen Sketch würdest du an der seriellen Ausgabe prüfen, und welche Beobachtung erwartest du? scaffolds: - id: serial-output-scaffold forConcept: serial-output From ff3c8287c326473d05ec241a906523064d3fc480 Mon Sep 17 00:00:00 2001 From: ttbombadil Date: Sun, 27 Sep 2026 20:46:14 +0200 Subject: [PATCH 3/5] ci: pin deterministic tutor quality validator --- .github/workflows/tutor-quality.yml | 53 +++++++++++++++++++++++++++++ .unosim-compatible-commit | 1 + 2 files changed, 54 insertions(+) create mode 100644 .github/workflows/tutor-quality.yml create mode 100644 .unosim-compatible-commit diff --git a/.github/workflows/tutor-quality.yml b/.github/workflows/tutor-quality.yml new file mode 100644 index 0000000..943a51a --- /dev/null +++ b/.github/workflows/tutor-quality.yml @@ -0,0 +1,53 @@ +name: Tutor Course Content Quality + +on: + push: + branches: [main] + pull_request: + branches: [main] + +permissions: + contents: read + +jobs: + deterministic-tutor-quality: + name: Deterministic Tutor quality hard gate + runs-on: ubuntu-latest + steps: + - name: Check out Course Content + uses: actions/checkout@v4 + with: + path: course-content + + - name: Read compatible UnoSim commit + id: unosim-version + shell: bash + run: | + ref="$(tr -d '[:space:]' < course-content/.unosim-compatible-commit)" + if [[ ! "$ref" =~ ^[0-9a-f]{40}$ ]]; then + echo "Invalid .unosim-compatible-commit" >&2 + exit 1 + fi + echo "ref=$ref" >> "$GITHUB_OUTPUT" + + - name: Check out compatible UnoSim validator + uses: actions/checkout@v4 + with: + repository: MoDevIO/UnoSim + ref: ${{ steps.unosim-version.outputs.ref }} + path: unosim + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version-file: unosim/.nvmrc + cache: npm + cache-dependency-path: unosim/package-lock.json + + - name: Install validator dependencies + working-directory: unosim + run: npm ci + + - name: Validate Course Content + working-directory: unosim + run: npm run validate:tutor-course-content -- "$GITHUB_WORKSPACE/course-content" diff --git a/.unosim-compatible-commit b/.unosim-compatible-commit new file mode 100644 index 0000000..4fe98aa --- /dev/null +++ b/.unosim-compatible-commit @@ -0,0 +1 @@ +65d2bb96d4f9a503f687ec0ab9abd23ac6abe94d From f53dcd4cd37152b5dc2b2768d356a0f0bdf9d698 Mon Sep 17 00:00:00 2001 From: ttbombadil Date: Sun, 27 Sep 2026 20:49:39 +0200 Subject: [PATCH 4/5] ci: update compatible UnoSim quality gate --- .unosim-compatible-commit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.unosim-compatible-commit b/.unosim-compatible-commit index 4fe98aa..e3f3638 100644 --- a/.unosim-compatible-commit +++ b/.unosim-compatible-commit @@ -1 +1 @@ -65d2bb96d4f9a503f687ec0ab9abd23ac6abe94d +aaa52fad3d778d4ec7ab9e304a27fe9626efb270 From ed30c76f85dfbd67fde237a9eb711c5b31e4ab82 Mon Sep 17 00:00:00 2001 From: ttbombadil Date: Sun, 27 Sep 2026 20:51:01 +0200 Subject: [PATCH 5/5] docs: explain tutor quality authoring gate --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index 552c575..de12972 100644 --- a/README.md +++ b/README.md @@ -64,3 +64,19 @@ learningObjectives: ``` Tutor repository data is normalized didactic data, never a system prompt. + +### Deterministic Tutor quality gate + +`tutor/quality-cases.yaml` contains small positive and negative activation +cases that reference Examples by ID. Every Topic needs both kinds of coverage. +The gate also checks the complete pinned bundle, Topic/Question reachability, +mastery capacity, and a strict LEARN-to-DEEPEN path. It deliberately does not +try to judge semantic teaching quality. + +`.unosim-compatible-commit` pins the exact UnoSim validator used by CI; it must +be updated deliberately when the Course Content adopts a newer validator +contract. With that UnoSim revision checked out locally, run: + +```sh +npm run validate:tutor-course-content -- /path/to/UnoSim-Examples +```