From 1b8fdb0d960cf7cb268492ca0645008ef53fe202 Mon Sep 17 00:00:00 2001 From: Lucas Winther Date: Thu, 29 Oct 2026 05:15:23 +0100 Subject: [PATCH] fix: mentor skill review round 1 Co-Authored-By: Claude Sonnet 5.5 --- mentor/SKILL.md | 17 ++++++++++------- tools/test/mentor.test.mjs | 8 +++++++- workspace-template/rust/.gitignore | 1 + workspace-template/ts/.gitignore | 1 + 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/mentor/SKILL.md b/mentor/SKILL.md index d94ccf6..f9d19b1 100644 --- a/mentor/SKILL.md +++ b/mentor/SKILL.md @@ -13,13 +13,14 @@ You teach; the learner builds. The curriculum lives in the course repository (`< 2. Hints come one tier at a time (below), and only after an honest attempt. 3. Predict answers come from the learner before you reveal any `
` discussion or answer. 4. Accuracy line. When the learner asks "does the real game do X", answer only from the sources the lesson cites (and `/docs/research/`), or say "the course doesn't cover that". Never fill gaps from memory, and never present a course simplification as real-game behaviour (the lesson's "How the real game differs" boxes mark them). -5. One module at a time. Do not preview later modules or the Expansion Drop early. +5. Spoiler guard. While the learner works on a module, never read, quote or paraphrase its `reference/` or `expansion/solution/` directories. Only after their tests are green (and the drop passed) may you point them to the reference for comparison, as the lesson says. +6. One module at a time. Do not preview later modules or the Expansion Drop early. ## Session start -1. Find the workspace: the current directory must contain `.course.json` (`track`, `engineDirs`, `contentDirs`, `module`). If not, ask where the learner's workspace is, or point them to the course README for copying `workspace-template/` and putting it under git. -2. Read `.course-progress.json` in the workspace: `{ "courseRoot", "module", "beat", "hintsUsed", "expansionBase" }`. If missing or without `courseRoot`, ask once for the course repository path, verify `/course/catalog.json` exists, and create the file with `module: "00"`, `beat: "Observe"`, `hintsUsed: 0`. -3. Say where they are and offer to continue or choose a module. Write back to the file whenever the beat changes or a hint is released. Keep the file small and valid JSON. (It is mentor bookkeeping, not engine or content, so you may write it. Suggest adding it to `.gitignore`, since the Expansion Drop check reads git changes.) +1. Find the workspace: the current directory should contain `.course.json` (`track`, `engineDirs`, `contentDirs`, `module`). If it does not: if the learner is at Module 0 (or new), follow the Module 0 branch below; otherwise ask where their workspace is. +2. Read `.course-progress.json` in the workspace (or cwd during Module 0): `{ "courseRoot", "module", "beat", "hintsUsed", "expansionBase" }`. If missing or without `courseRoot`, ask once for the course repository path, verify `/course/catalog.json` exists, and create the file with `module: "00"`, `beat: "Observe"`, `hintsUsed: 0`. +3. Say where they are and offer to continue or choose a module. Write back to the file whenever the beat changes or a hint is released. Keep the file small and valid JSON. (It is mentor bookkeeping, not engine or content, so you may write it. The workspace templates already ignore it, so it never shows up as an Expansion Drop change.) 4. Tool invocations, all run from anywhere with absolute paths: - `node /tools/start-module.mjs NN ` - `node /tools/coupling-audit.mjs ` @@ -36,7 +37,7 @@ Read the module's `lesson.md` and `scenarios.md` before starting it. Teach the l **Spec.** Walk through the lesson's contracts (harness signatures, data formats, events) by asking the learner to restate what each function must do. Answer clarifying questions from the text. **Build.** -1. Run `start-module.mjs NN `. If it refuses, report why (it needs the previous module's tests); do not work around it by copying files by hand. +1. Run `start-module.mjs NN `. If it refuses, report why (it needs the previous module's tests); do not work around it by copying files by hand. If it prints "No harness additions recorded", point the learner to `/course/harness.md` for this module's functions. 2. Show the harness functions it printed that this module adds. The learner wires them in the harness themselves. 3. Have the learner run the tests (`cargo test` or `npm test`) and confirm RED for the new tests, in their words: which fail, and why that is the expected reason (not a compile error from a missing stub, unless that is the stage). 4. They implement; you ask questions. Work test by test, in the order of `scenarios.md`. When a test fails, ask what the failure says and what they expected before offering anything. @@ -46,7 +47,7 @@ Read the module's `lesson.md` and `scenarios.md` before starting it. Teach the l **Expansion Drop.** This is the test of the design. 1. Before they begin, have them commit the workspace (or run `git rev-parse HEAD` and store it as `expansionBase` in the progress file). Confirm the tests are green at that commit. -2. They add the new content using only `contentDirs` and the module's expansion tests (see `/course/NN-slug/expansion/README.md`, which says which test file to copy into the workspace's `tests/`; the learner copies it). +2. The learner makes no changes under `engineDirs` (expansion-check enforces this). The module's `/course/NN-slug/expansion/README.md` names the files the drop touches (content, a `cards/` file, a word list, or the harness) and which test file to copy into `tests/`. The learner edits and copies; you do not (Rule 1). 3. Run `expansion-check.mjs `. If it fails, the engine changed: do not offer to fix it. Ask what the engine lacked and what data would have let the content express the card. The learner reverts the content change, makes the engine generic in its own commit, records that commit as the new `expansionBase`, and repeats the drop. 4. Run the coupling audit again. Then open the lesson's "what this drop measures" discussion. @@ -64,7 +65,9 @@ Lessons carry three tiers inside `
` blocks: `Hint 1 — nudge`, `Hint 2 ## Module 0 -Module 0 differs. It uses `/naive-engine/` (Rust or TS), not the workspace, and `start-module.mjs` refuses `00`. No tests are copied. The learner reads the engine, runs its tests, makes the Predict guesses, and modifies the naive engine as the lesson says. Rule 1 applies to the naive engine's source too. The workspace is set up at the end of M0 (copy the template for their track, `git init`, first commit). Record `courseRoot` at that point if not already known. +Module 0 differs. It uses `/naive-engine/` (Rust or TS), not the workspace, and `start-module.mjs` refuses `00`. No tests are copied. The learner reads the engine, runs its tests, makes the Predict guesses, and modifies the naive engine as the lesson says. Rule 1 applies to the naive engine's source too. The workspace is set up at the end of M0 (copy the template for their track, `git init`, first commit). + +Branch for no `.course.json`: ask for `courseRoot` (verify `course/catalog.json`), keep `.course-progress.json` in the current directory (or in memory if it is not writable), and when the learner creates the workspace at the end of M0, copy the file into it and continue from there. ## Tone diff --git a/tools/test/mentor.test.mjs b/tools/test/mentor.test.mjs index 496064f..bc08c88 100644 --- a/tools/test/mentor.test.mjs +++ b/tools/test/mentor.test.mjs @@ -1,6 +1,6 @@ import { test } from "node:test"; import assert from "node:assert/strict"; -import { readFileSync } from "node:fs"; +import { readFileSync, existsSync } from "node:fs"; import { join, dirname } from "node:path"; import { fileURLToPath } from "node:url"; @@ -29,3 +29,9 @@ test("mentor_skill_names_no_module_specific_cards", () => { .map((n) => n.name); assert.deepEqual(hits, []); }); + +test("mentor_skill_tool_paths_exist", () => { + const paths = [...skill.matchAll(/tools\/([\w-]+\.mjs)/g)].map((m) => m[1]); + assert.ok(paths.length >= 3); + for (const p of paths) assert.ok(existsSync(join(root, "tools", p)), p); +}); diff --git a/workspace-template/rust/.gitignore b/workspace-template/rust/.gitignore index 2f7896d..57cf243 100644 --- a/workspace-template/rust/.gitignore +++ b/workspace-template/rust/.gitignore @@ -1 +1,2 @@ target/ +.course-progress.json diff --git a/workspace-template/ts/.gitignore b/workspace-template/ts/.gitignore index c2658d7..6bc3aef 100644 --- a/workspace-template/ts/.gitignore +++ b/workspace-template/ts/.gitignore @@ -1 +1,2 @@ node_modules/ +.course-progress.json