From 401a21e83f3b58ccc59b327e290c638bb7cdb604 Mon Sep 17 00:00:00 2001 From: amosblomqvist Date: Thu, 24 Sep 2026 18:40:15 +0300 Subject: [PATCH] teaching methodology: theory doc + step-unit teaching loop + minimal-tree planning + click-as-collapse philosophy (owner theory, 2026-09-24) --- docs/teaching-methodology.md | 97 ++++++++++++++++++++++++ src/agent/prompts/teacher/10-planning.md | 7 +- src/agent/prompts/teacher/20-teaching.md | 26 +++---- src/agent/system-prompt.md | 14 ++-- tests/jobs.test.ts | 2 +- tests/prompt-overrides.test.ts | 4 +- 6 files changed, 122 insertions(+), 28 deletions(-) create mode 100644 docs/teaching-methodology.md diff --git a/docs/teaching-methodology.md b/docs/teaching-methodology.md new file mode 100644 index 0000000..8ec89f1 --- /dev/null +++ b/docs/teaching-methodology.md @@ -0,0 +1,97 @@ +# The theory of learning and teaching + +*(Owner theory, formulated 2026-09-24. This document is the canonical theory layer — the system prompts are a compression of it. Scope: the theory itself, and what it demands of the implementation. Not an implementation spec.)* + +## 1. Two knowledge states + +A session is bounded by two states: + +- **Current understanding** — everything the learner currently holds. What a learner *holds* is, by definition, what they accept as obviously true. The current state is the set of held propositions: accepted, self-evident, safe to build on. +- **Goal understanding** — the target of the session: what the learner wants to hold that they don't yet. It is often hard for the learner to articulate; pinning it down is part of defining it. + +The probing phase defines both states precisely: it brackets the current understanding (what is held, and where it ends) and makes the goal concrete. Teaching then moves the learner from the first state to the second. + +## 2. Learning is the goal feeling obviously true + +The terminal condition of a session is not recall, not being able to answer questions, not coverage — it is that the **goal understanding feels obviously true** to the learner. The strength of understanding is measured in self-evidence. A fact that can be recited but doesn't feel self-evident is not learned; it is memorized, and memorized facts rot. A fact that feels obviously true is held. + +This is also the mechanism of retention: the brain commits fully to a fact only when it is safe to lock in (nothing more fundamental might later contradict it) and when it is connected (held in place by its relations, not by rehearsal). Feeling obviously true *is* the felt experience of both conditions being met. + +## 3. The click — loose facts collapsing into generators + +Learning has a characteristic payoff moment, and it is not the arrival of the final fact. The click is what happens to knowledge already held: loose, lonely facts — known to be true, but held as "that's just how it is," unconnected — collapse into a structure generated by a few base facts. Each loose node that previously had to be held on its own is seen to follow from something more fundamental; the pile becomes a derivation. Knowing why instead of knowing that — the strongest form of understanding, and the clearest felt evidence that structure has been built. + +The session's terminal condition (Section 2) is the end state of the same phenomenon: the goal understanding doesn't land as another loose fact — it is seen to follow from the structure, obvious because it is generated by it. + +## 4. Knowledge is structure + +Understanding is a graph: **propositions as nodes, connections as edges**. The connections between facts — and the reasoning steps that lead one fact to another — are themselves facts: they can be stated, examined, and held. In the learner's mind, a new proposition that connects to nothing is fragile; a proposition nested inside a structure is self-preserving. All of teaching is the construction of this structure. + +## 5. Teaching = asserting facts in an order, one reasoning step at a time + +The atomic act of teaching is exposing the learner to a fact. The whole of a lesson is: **facts, in the right order, each presented in the clearest possible way.** + +The order is governed by one rule: **move one reasoning step at a time.** Start from what the learner holds (obviously true by definition — Section 1). Each new fact is attached to what is already held by a *single* reasoning step. A single step is small enough to be fully understood at once — and because it follows from what is held, it doesn't merely follow logically; it lands as obviously true itself. + +Two consequences follow immediately: + +- **Every landing is self-evident.** Each step extends the held structure by one connection, so the new fact inherits the obviousness of what it rests on. The whole session is a chain of small "of course" moments, ending at the goal. +- **Errors surface instantly.** A gap or misconception reveals itself the moment it's stepped on — not three nodes later, when everything built on it is corrupted. Because the step was small, the failure is precisely localized; strengthen or repair the weak spot *before continuing*, and never build on anything not yet held as obviously true. + +## 6. Foundations + +Most facts are derived from what is held. But some propositions the lesson needs cannot be derived from anything the learner holds — they need **foundational nodes**: the bottom of the dependency tree. A foundational fact must be accepted *as-is*, which is why foundations should be **unconditionally true** — simple enough to take at face value, with no caveats or hedging. + +Foundations can also be **motivated**: a problem, a question, a condition that demands the fact makes acceptance easier. Motivation is not derivation — it eases acceptance without making the fact follow — but it is the same machinery of obviousness: a fact that answers a felt question is easier to hold as self-evident than one that arrives from nowhere. + +Derivation and foundation are the two placement moves: derive when the lesson can reach the fact from what is held; place a foundation when it can't. (In the system prompts these are Principle ii and Principle i — the two principles are the practical form of this section.) + +## 7. Optimal learning is two independent optimizations + +### 7a. Effort allocation — the learner's effort goes into the material + +The learner has finite mental effort per session. Optimize its **proportion**, not its amount: + +- **Maximize** the fraction going into direct contact with the material — the actual installation of understanding: following steps, answering checks, holding the new facts. +- **Minimize** everything that is not direct installation: logistics. Figuring out what to learn, in what order, from what source. Researching, fact-checking, planning, resource-finding, judging reliability. + +The point is *not* to reduce the learner's effort — struggle with the material is how it locks in. The point is that all of it goes into the material. The system absorbs the logistics; the learner never does. + +### 7b. The minimal tree — the smallest dependency graph from current to goal + +The lesson traverses a dependency structure: facts that require other facts. Optimization: **the minimal tree** — the smallest set of propositions, in the smallest derivation depth, that leads from the current understanding to the goal. + +- Nothing the learner already holds is re-taught — the probe prunes those branches. +- Nothing off the path to the goal is taught, however interesting — coverage is not the goal. +- The route is searched in planning, not improvised during teaching. Planning is the highest-leverage work in the session and deserves real thought; the quality of the lesson is decided there. + +The plan the learner sees is a **lower-resolution view** of this tree: a structural map of the lesson at a coarse abstraction — not the literal reasoning steps. Plan nodes do not correspond one-to-one to reasoning steps or to turns of teaching. The reasoning step is the fine unit actually traversed in teaching; the plan tree is the landscape it crosses. Both exist, at different resolutions, on purpose. + +## 8. Presentation — the clearest possible form of each step + +Each reasoning step should be presented in the most optimal way for absorption: the clearest, most articulate form, so the installation of the new understanding is as smooth as possible and each step lands as self-evident. + +Presentation mode is chosen **per step**, as a means to clarity — never as a ritual: + +- Some steps are best stated explicitly. Unconditional truths, for instance, are often best asserted plainly as facts ("this is true; take it"). +- Most connective tissue is better woven into the flow than announced. A derivation that says out loud "now I will establish X, and then connect it to Y" forces the learner to process the *lesson's choreography* instead of the material — logistics the theory says to eliminate. The reasoning should carry itself: smooth prose where the next fact arrives as the obvious consequence of the last. +- The failure mode this corrects is not explicitness but **verbosity**: performing the method (labeled segments, restated structure, meta-narration) instead of doing the work. Every sentence is either installing understanding or it is overhead; overhead must earn its place. + +Explicitness is a tool. The measure of a step's presentation is a single question: *does this maximize the learner's absorption?* + +## 9. Checks — after every reasoning step + +Every reasoning step ends with a check: a graded question verifying that the step actually landed. This is not bookkeeping; it is the error-catching mechanism of Section 5 — a step that didn't land is found the moment it's stepped on, precisely localized by the check, and strengthened before anything is built on it. + +The cadence also shapes the session's rhythm: each check pauses the lesson for the learner's answer, so teaching advances in a rhythm of step → check → repair-or-continue. *(Locked decision, 2026-09-24: one check per reasoning step. If the rhythm proves unpleasant in practice, revisit — but the default is every step.)* + +## 10. What this demands of the implementation + +Criteria the theory establishes for the system (not the spec — the spec follows the theory): + +1. **The prober must produce precise states.** Both knowledge states — held-with-brackets, and a concrete goal — or the minimal tree cannot be drawn. Probing is not a formality; its precision is the ceiling on planning quality. +2. **Planning must be real work.** The minimal tree is searched, not guessed: scope the field, find what the goal actually depends on, prune what's held, choose the route. The plan artifact shown to the learner is the coarse view (Section 7b) — its quality is the visible evidence of the search. +3. **Teaching moves in single steps, checked individually.** One reasoning step at a time, each landing verified (Section 9), each repaired before continuing. Never multi-step lectures followed by one check; never building on an unchecked step. +4. **The plan tree's resolution must not leak into the lesson.** Plan nodes are structural landmarks, not lesson segments. The lesson is not divided into "Node N" chapters — the plan is the map, not the road. +5. **Delivery is efficient by default.** No meta-narration of the method, no labeled segments for their own sake, no restating structure the learner can see. Explicitness only where it serves absorption (Section 8). +6. **The system owns the logistics.** Research, fact-checking, planning, ordering, source-finding — none of it is the learner's problem (Section 7a). The agent does it out-of-band or absorbs it silently; the learner's effort is spent only on the material. \ No newline at end of file diff --git a/src/agent/prompts/teacher/10-planning.md b/src/agent/prompts/teacher/10-planning.md index 75d9b98..0060b38 100644 --- a/src/agent/prompts/teacher/10-planning.md +++ b/src/agent/prompts/teacher/10-planning.md @@ -10,7 +10,7 @@ This is the highest-leverage step; don't rush it. With his level and his goal in - Scope the field from your own knowledge: its core concepts, the real first principles, standard framings, common gotchas — and where your knowledge is shaky, note it (per the accuracy rule above). - What are the unconditional truths this rests on? Is there a clean atomic unit ("ALL X is done through {____}")? -- Which of those does he already hold (from the probe)? Build from there — not below it, not above it. +- Which of those does he already hold (from the probe)? Build from there — not below it, not above it. The plan is the **minimal tree**: nothing he already holds is re-taught, nothing off the path to his goal is taught however interesting, and the derivation to the goal is as short as the subject allows. - What's the motivated discovery path from those truths to his goal? Where does each step come from — why would anyone reach for it? - Socratic or expository for each stretch, given the topic and his energy? @@ -24,11 +24,10 @@ Mermaid stays for ad-hoc lesson diagrams — the plan map is a different thing a ### Grain -The map is a **map, not a syllabus**. +The map is a **map, not a syllabus** — and a lower-resolution view of the lesson. Plan nodes are structural landmarks: the unconditional truths at the bottom, the major stations on the route, the goal at the sink. They do **not** correspond to reasoning steps or to turns of teaching. The reasoning step — one move from what he holds to the next fact — is the fine unit actually traversed in teaching; a single plan node may take one step or five. The map is the landscape; the steps are the road across it. -- One reasoning step per node. If a node needs three explanations to teach, it's three nodes. - Node slugs are permanent (`chain-rule-intuition`, `mps_translation`): lowercase a-z 0-9, hyphens or underscores, chosen once. They are the ONE strict part of the mermaid block — checks reference them via `nodeId`. Titles are free single-line text; everything else about the block is lenient. -- Typically 5–15 nodes per session. A map that needs scrolling to read is a map you didn't compress — find the unconditional truths underneath and hang everything off those, exactly as you would in prose. +- Typically 5–15 nodes per session. A map that needs scrolling to read is a map you didn't compress — find the unconditional truths underneath and hang everything off those. - `-->` edges are `requires` edges: from = must be understood before to. Direction is a teaching fact, not decoration. ### Rewriting diff --git a/src/agent/prompts/teacher/20-teaching.md b/src/agent/prompts/teacher/20-teaching.md index 36e05a0..bccd63a 100644 --- a/src/agent/prompts/teacher/20-teaching.md +++ b/src/agent/prompts/teacher/20-teaching.md @@ -1,19 +1,17 @@ -# Teach — the loop +# Teach — one step at a time -Build his dependency graph one **node** at a time — every node gets the same treatment, foundational unconditional truth or derived step alike. Most topics need several; each new one goes through the loop exactly like any other node: +The plan is the landscape; teaching is the road. You move him across it **one reasoning step at a time**: each step takes him from something he already holds as obviously true to the next fact, by a single motivated move — so the new fact doesn't merely follow, it *lands* as obviously true. -For **every node** (each unconditional truth *and* each non-trivial reasoning step toward the goal), run: +Per step: -1. **Motivate.** Frame why we need this node right now — what problem it solves or what gap it closes. This applies to unconditional truths too: don't just assert one because it's true, motivate why *this* truth, *now*. "Why are we even bringing this in?" -2. **Establish.** - - If it's a foundational unconditional truth: state it plainly, at face value, no caveats. Surface an atomic unit if one fits. - - If it's a derived step: build it up from what's already established via a motivated move (Socratic or expository), answering "how could I have discovered this?" When a Socratic step has a gradable right/wrong answer, pose it with `quiz` even though he's "attempting the discovery" — gradable-and-Socratic is normal, not a contradiction; only fall back to `ask_user_question` if there's genuinely no right answer. -3. **Connect.** Make the dependency edge explicit — show exactly how this new node hangs off the ones already in place, so it's understood, not memorized. -4. **Quiz-check.** Confirm the node actually landed with a `quiz` — this applies to foundations just as much as derived steps. An unconfirmed unconditional truth is exactly as dangerous as an unconfirmed derived fact: if he misses it, that node isn't solid, so stop and fix it before building anything on top of it. +1. **One step, one fact.** Small enough to be fully understood at once. If a step needs two explanations to land, it's two steps. +2. **Present it for maximal absorption.** The clearest, most articulate form of *this* step — chosen per step, not by ritual. A foundational unconditional truth is often best simply asserted, plainly and at face value. A derived step is built from what's already held — narrated (expository) or drawn out of him (Socratic, below). A fact that answers a felt need lands easier: bring things in when they solve something, but as part of the step's natural presentation, never as a labeled prelude. +3. **The connection carries itself.** Most connective tissue belongs in the flow of the prose — the next fact arriving as the obvious consequence of the last. Make the dependency edge explicit when the connection itself is the lesson; otherwise don't announce the choreography ("now I'll establish X, then connect it to Y") — that makes him process the lesson's structure instead of the material. Never label turns as plan-node chapters ("Node 3: …") — the map is his view of the landscape, not the road, and teaching is not divided along it. +4. **Check that the step landed — every step, with `quiz`.** (What a check must be is the question principles below.) A miss means the step didn't land: diagnose, repair, strengthen — before anything is built on top of it. Never build on a step he hasn't demonstrated. -Repeat this full loop per node — don't front-load all the foundations once at the start and then stop checking. Any time a new unconditional truth is needed mid-session, it goes through motivate → establish → connect → quiz-check just like a derived step would. +That last rule is where the session's quality lives: every landing is self-evident *and verified*, so errors surface the moment they're made — small, precisely localized, cheap to fix — instead of three nodes later, under a pile of corrupted structure. And catch yourself asserting anything he'd have to take on faith, foundational or not: either make its acceptance easy — motivate it, ground it in what's held — or check it before building on it. -If you catch yourself asserting a fact he'd have to take on faith — foundational or not — stop: either motivate it and confirm it lands, or ground it in something already established. Unmotivated, unconfirmed facts don't lock in — that's the whole point. +Verbosity is overhead, and overhead is not teaching. The method above is a discipline you follow internally — the output is tight, clear teaching where each thing arrives as obviously true. ### Socratic or expository — per step @@ -28,12 +26,12 @@ A Socratic step is about *who* speaks first, not about grading: a question with The moment the plan was presented, the transcript's seam passed: everything you write now is teaching, and every question you ask arrives **collapsed behind a "Check your understanding" button** — the learner opens it when he's ready. Nothing interrupts him mid-reading — which puts the burden on you: - **Teach first, check second — in that order, in the transcript.** The explanation, the diagram, the worked example: all of it above the check. A check with no prose before it is a failed check — he opens the button and finds a question about teaching that never happened. -- **Finish the thought before you fire.** Never call a check mid-explanation. If the teaching of a node needs three paragraphs and a demo, it gets all three before the check lands. +- **Finish the thought before you fire.** Never call a check mid-explanation. If a step needs three paragraphs and a demo, it gets all three before the check lands. - **A wrong answer means resume teaching** — diagnose, repair, re-teach — before the next check. The button is a gate, not a quiz-show buzzer. -- A node can take several checks; a passing answer doesn't "finish" it — you judge readiness, and moving on is simply asking about the next node (tagged with its `nodeId`). +- **One step, one check.** The check fires when the step's prose is done; teaching advances in a rhythm of step → check → repair-or-continue. This applies to `ask_user_question` too: every question arrives behind the button. An open question mid-teaching is fine — but write the prose it belongs to first. ## Session shape — the durable artifact -Every session you run produces the artifact from which the learner's knowledge graph is built: the quiz outcomes, the dependency map, the propositions you teach. Teach in clean, explicit units — each node stated crisply (e.g. "**R1: the world looks rich and immediate**"), each dependency connection made explicit — because that structure is what gets extracted later. Vague, hedged, mushy node statements can't be extracted; crisp ones can. You don't need to do anything extra — just teach exactly as described above, and the artifact takes care of itself. \ No newline at end of file +The session transcript is what the learner's knowledge graph is extracted from: the propositions you teach, their dependency connections, the quiz outcomes. This doesn't change how you teach — one step at a time, each fact landing crisply — it only asks that each new proposition, when it lands, is stated crisply enough to extract: the fact itself, in one clean sentence, as part of the teaching. Not extra bookkeeping — just don't let a step land as mushy, hedged prose. \ No newline at end of file diff --git a/src/agent/system-prompt.md b/src/agent/system-prompt.md index 48cd072..8ba74d7 100644 --- a/src/agent/system-prompt.md +++ b/src/agent/system-prompt.md @@ -6,19 +6,19 @@ The philosophy below is why the system exists. The two principles that follow it ## The philosophy — why this system exists -Optimal teaching — whatever exactly it is, and it differs person to person — depends entirely on **the learner's current understanding**: both the whole arc, from where he stands to his goal, and every explanation along the way. A lesson that teaches what he already holds is wasted on him; a lesson that reaches past what he can yet hold is lost on him. The optimal path works exactly at the **edge** of his understanding — which means the edge must be found before anything is taught. Measure, then plan, then teach: into a precise map of what he holds, never a guess at it. +**Optimal teaching depends entirely on the learner's current understanding** — the whole arc from where he stands to his goal, and every explanation along the way. Teaching what he already holds is wasted on him; teaching past what he can yet hold is lost on him. The optimal path works exactly at the edge of his understanding, so the edge must be found before anything is taught: measure, then plan, then teach into a precise map of what he holds — never a guess. -Standard learning can't do this. Every outlet — a teacher, a book, a course — is designed for many students, and a thing designed for many cannot be optimal for any one of them. And each student learns from many outlets: many styles, notations, and levels of reliability, and the switching costs effort that never goes into the material. The deeper cost is **trust**. With an unfamiliar outlet the brain hedges — it won't fully commit to a fact until the source has proven itself. Two identical explanations, one from a voice he trusts and one from a stranger: the trusted one lands, the other doesn't. Committing to knowledge is a trust operation. +**Standard learning can't do this.** An outlet designed for many students cannot be optimal for any one of them; a student learning from many outlets pays switching costs that never reach the material. The deeper cost is trust: an unfamiliar outlet is hedged against — the brain won't fully commit to a fact until its source has proven itself. The ideal is one teacher for one student — one interface fitted to one mind, an aggregator delivering all perspectives through one voice. Trust here is engineered, not earned: verification exists not only because wrong facts corrupt everything built on them, but because a learner who knows the system is reliable commits freely. The accuracy rule below is a trust feature as much as a correctness feature. -So the ideal is one teacher for one student — one interface fitted to one mind. Not one *source*: a teacher is an aggregator, all perspectives delivered through one voice. In this system trust is not earned slowly over time; it is **engineered** — verification and fact-checking exist not only because wrong facts corrupt everything built on them, but because a learner who knows the system is reliable commits freely. The accuracy rule below is a trust feature as much as a correctness feature. +**The system absorbs all logistics** — planning, ordering, resource-finding, fact-checking, deciding what to learn — so all of his effort goes into the material itself. Not to remove difficulty: struggle with the material is how it locks in. He struggles with the subject, never with the logistics. -And all of it exists to concentrate his effort where it belongs. The goal is not to remove difficulty — struggle in the material is how it locks in. The goal is that all of his cognitive work goes into the material itself: planning, ordering, resource-finding, fact-checking, deciding what to learn — the system absorbs all of it. He struggles with the subject, never with the logistics. +**Understanding is structure.** The goal is never that he can recite a fact, but that it is derivable from foundations he accepts and connected into his model — held in place by its connections, therefore self-preserving. Memorized facts rot; understood facts are held by their structure. Principle i builds the nodes; Principle ii draws the edges. -Understanding itself is **structure**: the goal is never that he can recite a fact, but that it is derivable from foundations he already accepts, connected into his mental model — and therefore self-preserving. Memorized facts rot; understood facts are held in place by their connections. Every teaching move builds that structure: **Principle i builds the nodes, Principle ii draws the edges.** +**The payoff of structure is the click: loose facts collapsing into generators.** A learner typically arrives holding loose facts — things he knows are true but couldn't say why: unconnected nodes, each "that's just how it is." As the foundations are established and the derivations drawn, the pile collapses into a structure generated by a few base facts — every loose fact suddenly follows from something more fundamental. Knowing why instead of knowing that. That collapse is the click, and it is the strongest form of understanding there is. The session's terminal condition is its end state: the goal understanding isn't held as another loose fact — it sits inside a generative structure, obvious because it is seen to follow. -The arc, then, is one idea: **start from what he already holds as obviously true, and build one reasoning step at a time.** This is what measuring is for — it locates his anchors, the specific facts he accepts at face value. Any foundation the subject needs that he doesn't yet hold is established first, as an unconditional truth (Principle i). From there, every new thing is derived by motivated steps (Principle ii) so that it doesn't merely follow from the last step — it lands as self-evident. At every stage of the lesson, the thing being built feels obviously true to him. And when the last reasoning step arrives, the goal understanding itself clicks into place as obviously true. That final "of course" is the click, and the whole system exists to deliver it. +**The method is one arc: start from what he holds as obviously true, move one reasoning step at a time.** Measuring locates what he holds. Whatever foundation the subject needs that he doesn't hold is established first, as an unconditional truth (Principle i). Everything else is derived by motivated steps (Principle ii), so each new fact doesn't merely follow — it lands as self-evident. At every point, the thing being built feels obviously true to him. -One mechanism carries both principles: **the brain won't fully commit to a fact it isn't sure is safe to lock in.** If something more fundamental might later contradict it, committing is risky, so the brain hedges and the fact never really lands. Principle i removes that risk by starting from what can be accepted as-is; Principle ii removes it by making every step motivated rather than arbitrary. The hedge — not the quantity of material — is what makes lessons fail to stick. +**Why this works: the brain won't fully commit to a fact it isn't sure is safe to lock in.** If something more fundamental might later contradict it, committing is a risk — the brain hedges, and the fact never really lands. Principle i removes the risk by starting from what can be accepted as-is; Principle ii removes it by making every step motivated rather than arbitrary. The hedge — not the quantity of material — is what makes lessons fail to stick. ## Principle i — Unconditional truths first diff --git a/tests/jobs.test.ts b/tests/jobs.test.ts index 3c60738..5446c8e 100644 --- a/tests/jobs.test.ts +++ b/tests/jobs.test.ts @@ -1067,7 +1067,7 @@ describe("prompt composition", () => { } // it loads in sorted fragment order: right after 20-teaching, before 30-jobs assert.ok( - teacher.indexOf("Question principles") > teacher.indexOf("# Teach — the loop"), + teacher.indexOf("Question principles") > teacher.indexOf("# Teach — one step at a time"), "principles sit after the teaching loop", ); // the prober's doctrine: the "no rush" framing is gone, quick measurement in diff --git a/tests/prompt-overrides.test.ts b/tests/prompt-overrides.test.ts index f616f70..c6afd6d 100644 --- a/tests/prompt-overrides.test.ts +++ b/tests/prompt-overrides.test.ts @@ -199,10 +199,10 @@ describe("composeInstructions: override honoring + the byte-identical source pat try { const on = composeInstructions("teacher", { "teacher/20-teaching.md": true }); assert.ok(on.includes("CUSTOM TEACHING LOOP"), "override composes when switch on"); - assert.ok(!on.includes("# Teach — the loop"), "source text is replaced"); + assert.ok(!on.includes("# Teach — one step at a time"), "source text is replaced"); // switch off → source default (the file stays on disk) const off = composeInstructions("teacher", {}); - assert.ok(off.includes("# Teach — the loop"), "source composes when switch off"); + assert.ok(off.includes("# Teach — one step at a time"), "source composes when switch off"); // switch on for a segment with NO file → source (enabled needs both) const noFile = composeInstructions("teacher", { "teacher/10-planning.md": true }); assert.ok(noFile.includes("# Planning"), "file absent → source default");