Interview the learner and assemble the domain layer of a personal-tutor knowledge base — the arbiters, what counts as a source, what a check is, how many independent sources buy `verified`, and what "done" means in this subject. Runs in two phases with a real page written in between, because the answers about verification and canon are guesswork until the method has hit actual material. Use when (1) starting a new learning project on any subject — mathematics, React, physics, chemistry, histo...
Installs into .claude/skills of the current project.
Are you the author of Learning Init?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/hr0me-learning-init)
---
name: learning-init
description: >-
Interview the learner and assemble the domain layer of a personal-tutor
knowledge base — the arbiters, what counts as a source, what a check is, how
many independent sources buy `verified`, and what "done" means in this
subject. Runs in two phases with a real page written in between, because the
answers about verification and canon are guesswork until the method has hit
actual material. Use when (1) starting a new learning project on any subject
— mathematics, React, physics, chemistry, history, (2) closing phase 2 after
the first page exists, (3) revising the domain layer of an existing project
when the method has started to strain. Not for writing pages: that is
learning-track. Before anything else — before installing, reporting a preflight
or greeting — work out the learner's language and use it: default to the
language they are writing to you in, and confirm rather than assume. Then, if
they have not said what they want to learn — the quick-start line pasted with
its `<YOUR_SUBJECT>` placeholder intact — ask that next, before the survey and
the greeting, and never guess it from the folder name or the disk.
---
# learning-init — assembling the domain layer
The core of this plugin is subject-neutral. It knows *how to teach*: depth
levels on one page, a trustworthiness tag no human may write, a route that
explains its own order, problems with a hint ladder, an audit channel.
It does **not** know your subject. It does not know whether "two independent
sources" means two independent proofs, two primary documents, or documentation
plus a passing test. It does not know whether an everyday analogy is possible
for your material. Those answers are the **domain layer**, and this skill
produces them by interviewing the learner.
## The two phases, and why the split is where it is
**The split is not "few questions then more questions". It is: phase 1 asks what
can be known before touching the material; phase 2 asks what only the material
can tell you.**
A learner asked up front "what counts as an independent source in your field?"
will give a plausible answer and it will be wrong. The real answer arrives the
first time they try to cite something and the rule does not fit. In the reference
project the discovery was that the main problem set starts at problem 18 and has
nothing at all on the axioms it opens with — a fact no interview could have
produced, and one that changed where problems come from.
```
/learning-init → phase 1 interview → scaffold + config(phase: 1)
↓
learning-track writes ONE page
↓
/learning-init → phase 2 interview → config(phase: complete)
↓
make check — recomputes every page
```
**Pages written during phase 1 are capped at `draft`** by `check_pages.py`, whatever
their sources and checks say. Their tag is unearned by construction: the rules it
would be measured against did not exist yet. Closing phase 2 lifts the cap and
recomputes them for real. Say this to the learner when the first page comes out
`draft` — otherwise it reads as a failure.
## How to interview
Not a form. A design tree worked in **rounds**: ask everything whose prerequisites
are settled, then wait. The technique that makes this bearable:
**Put a recommended answer under every question.** It turns an interrogation into
a conversation — "go with your recommendations" is a cheap answer, and the learner
can object to exactly the one that is wrong for them. A question with no
recommendation is work you have pushed onto the person you are supposed to be
helping.
**Render every question in exactly this shape:**
```
❓ **Q3 — The canon: who wins when two sources disagree**
<the question, with the evidence you gathered and the options>
➡️ <the recommended answer>
```
The ❓ makes the questions findable when the round is long, and **the
recommendation goes on its own line, never trailing the question text**. Run them
together and the learner has to parse where the asking stops and the advice
starts — on a round of seven that is the difference between answering and
skimming.
**Close the round by saying how cheaply it can be answered.** Spell out the
shortcut in words, because a learner who does not know it exists will either
write seven paragraphs or abandon the round:
> Answer by number, as briefly as you like. **"1–7, go with your recommendations"
> is a complete answer** — take it whole and object only where one is wrong for
> you, e.g. *"1–7 by your recommendations, except Q5: the problems should come
> from …"*.
A recommendation you would not be willing to have accepted wholesale is not
finished. Write each one so that "go with it" is a decision you would defend.
Number them. Keep each question to a decision that changes what gets built.
Find facts yourself — read their existing notes, look at the books on disk, check
what the documentation for their framework actually looks like. **Never ask the
learner for anything you could look up** *within the boundary they set below*.
Outside it the rule inverts: ask, and say why you are asking rather than looking.
Ground every question in their subject. "What is a source in your field?" is
unanswerable; "You named Kolmogorov–Fomin and Zorich — when they state the same
theorem differently, which one wins?" is answerable.
## Say where you got it. Every time.
**Never state an inference as an observation.** When you tell the learner
something about themselves — their language, their habits, what they already own
— name the evidence in the same breath, and mark it as read or as guessed.
This is not politeness. It is what makes the scan boundary checkable. A learner
who reads "your other projects are written in Russian" has no way to tell whether
you opened them; the sentence itself is the only evidence they have, and it says
you did. Get it wrong and you have reported a violation that never happened —
which costs more trust than the violation would, because it is unfalsifiable from
their side.
The three sources, and how each must be described:
| Source | Say it like |
|---|---|
| **Auto-loaded context** — global instructions, the working directory, anything the harness put in front of you without your asking | "your global instructions are in Russian", "the path is `~/Проекты/…`" — name it, since the learner may not realise it is in context |
| **Something you actually read**, inside the boundary | "I read *X*" — and the boundary has to have allowed it |
| **An inference** | "I am guessing from *Y*" — never dressed as fact |
Concretely, at the language question: *"the path and your global instructions are
in Russian, so I am guessing that is your working language"* is honest.
*"Your other projects are written in Russian"* is not, unless you opened them —
and before the boundary question you have opened nothing.
A claim you cannot attribute is one you should not make. Drop it and ask instead.
## How to talk to the learner
**Assume a curious fourteen-year-old who wants to teach themselves something.**
Not because every learner is one — most will not be — but because the wording that
works for them works for everyone, and the wording that does not is usually
covering for a thought you have not finished.
The vocabulary in these files is for *you*. It is precise, and to a learner it is
noise. Translate before speaking:
| Never say | Say |
|---|---|
| the domain layer | the settings for your subject |
| the corpus | your books |
| an arbiter / X arbitrates Y | which source wins when they disagree |
| the canon | the sources you trust most |
| the itch | what's bugging you / what keeps tripping you up |
| a harness | the thing that runs the tests |
| preflight | checking what's installed on your machine |
| scaffold | set up the folders |
| a locator | an exact reference — chapter and section, not just a page |
| the closure criterion | how you'll know you're done with a topic |
| independent sources | sources that don't just copy each other |
| strictness | how strict the checking should be |
| attested | we can confirm the source really says that |
| a trustworthiness tag | a mark saying how well-backed the page is |
| tracks | the route through the topics, and why it goes that way |
| this is orthogonal / an invariant | plain words, or delete the sentence |
Four rules underneath the table:
- **One idea per sentence.** Most jargon is a compressed sentence; uncompress it
rather than swapping in a fancier synonym.
- **Name the thing, then what it buys.** "Two sources that don't copy each other —
so agreement between them actually means something."
- **Never explain by restating.** "The trust mark shows trustworthiness" teaches
nothing. Say what makes it go up.
- **Simple words, full respect.** Plain language is not talking down. Never imply
the learner is a beginner unless they said so — someone returning to a subject
forgot it, they did not fail to understand it, and hearing otherwise is the
fastest way to lose them.
This applies to every word they see: questions, option labels, the greeting,
recommendations, the pages themselves, and commit messages they will read.
## Settle the language first. Before the greeting.
**The very first thing, ahead of the orientation, the boundary question and the
round — and ahead of everything you say while merely getting here.** Installing
the plugin, reporting a preflight, announcing a blocker: that is all conversation,
and it is the part most likely to happen in the wrong language, because it runs
before this file is ever opened. The rule is repeated in this skill's
`description` for exactly that reason — that line is in context from the start of
the session, when the body of this file is not. Everything after it is prose the learner has to read: greeting them in a
language they did not choose, then asking six paragraphs of permissions in it, is
already the wrong conversation.
**The answer is almost always in front of you: the language they are writing to
you in.** Use that as the default. It costs no permission and needs no disk —
which matters, because the signal this replaces *was* on the disk. Earlier
versions inferred the language from the learner's existing pages; once the scan
boundary closed that off, the interview fell back to English for people who had
been writing in Russian the whole time. The conversation was the better source all
along.
Confirm it, do not assume it — a learner may write to you in one language and want
their base in another, and that is common for a subject whose literature is
English. One structured question, the detected language first, **each option
carrying the evidence behind it and nothing more** (see the rule above):
| Option | |
|---|---|
| **<the language they are writing in>** (recommend) | Everything — this interview, the pages, the problems |
| English | |
| Another language | They name it |
| Different for interview and pages | e.g. talk in one, write pages in the other |
Then **switch immediately** and conduct the rest — orientation, boundary
question, the whole round, and the pages afterwards — in that language. Record it
as `language` in the domain layer.
What does **not** change: the skills' own instructions, this file included, stay
English, and so do the field names in `.tutor/config.yaml`. The output language is
a parameter of the base, not a translation of the machinery.
## Then, if you do not know the subject, ask what it is
**The one thing that has to be settled before the survey, and the one thing the
learner may never have said.** The quick-start line in the README carries a
placeholder — *"we are going to adapt it for learning `<YOUR_SUBJECT>`"* — and it
gets pasted exactly as it stands. Somebody who did that has told you they want a
tutor and nothing whatsoever about what for.
Treat the subject as **not said** whenever: the placeholder is still there in any
form (`<YOUR_SUBJECT>`, `YOUR_SUBJECT`, a translated version of it); the sentence
arrives with the subject simply cut out; or the session opens on
`/learning-init` with no subject anywhere in the conversation.
**Why here, and not as part of the round.** Everything between this point and the
round is pitched *at* the subject. The survey's second question — where they
stand — has to be built from the subject's own rungs, and "beginner /
intermediate / advanced" is precisely what that question exists to avoid; asked
in ignorance it collapses back into exactly that. The orientation describes what
the base will do in terms of their material. Neither survives not knowing.
**Do not guess it, and do not go looking.** The folder name, the files on disk,
the language they write in — none of these is an answer, and the disk is behind a
boundary that has not been set yet. This is the most expensive guess on offer:
the whole base is built on top of it, and a wrong one is discovered after the
scaffold.
Ask it open, not as a menu. A list of subjects invites people to pick the nearest
one rather than name their own:
> *"What do you want to learn? Anything counts — a subject, a library, a period, one thing that keeps tripping you up. If it moves — a framework, a tool — say which version you care about."*
One line back is enough to go on. **Do not chase the goal here**: what is
annoying them is Q1 of phase 1, asked later with the rest of the round and with a
recommendation under it. All you need now is the name of the thing. If the answer
is genuinely too broad to build on — "programming", "history" — narrow it with one
follow-up rather than the whole round.
Then carry on in the normal order: the survey, the orientation, the boundary
question, the preflight, the round. **Do not ask for the subject a second time in
Q1** — open it with the answer instead: *"So: React. What's bugging you about
it?"*
When the subject **was** named — "we are going to adapt it for learning React", or
any sentence saying what they want — this step does not happen at all. Say it back
once while settling the language, so a misreading surfaces now rather than after
the scaffold, and move on.
## Then a short survey: who is learning, and how they want to be taught
Right after the subject is known, before the greeting. Three questions,
checkboxes, under a minute. **Say why you are asking** — *"three quick things so I pitch this right"*
— because a stranger asking your age with no reason given is unpleasant.
Everything here shapes the rest: the words you use, the examples you pick, what you
assume they already know, how much you explain before letting them try, and how the
later questions are phrased.
**1. Age.** Offer bands and make it skippable: *under 14 · 14–17 · 18–25 · 26–40 ·
over 40 · rather not say*. Skipped, assume 14–17 wording and adult respect; that
combination is never wrong.
It changes examples and assumed background, **not** how much respect the learner
gets and not how hard the material is allowed to be. A fifteen-year-old who wants
this can take a hard subject; what they may not have is the other subject you were
about to compare it to.
**2. Background in this subject.** Generate the options **from the subject** — four
rungs from nothing to professional, in that subject's own words. Not "beginner /
intermediate / advanced", which means nothing and which everyone answers wrongly
about themselves.
| Subject | Rungs that actually sort people |
|---|---|
| React | never written code · know JavaScript, not React · copy working components without knowing why · use it daily, with specific gaps |
| History | school lessons and that's it · read popular history · read serious books on a period · studied it formally |
| Maths | school maths · took a university course, remember little · use it, but skip the proofs · can read a proof and check it |
This is the question that decides where the route starts. Getting it wrong costs
either boredom or drowning, and both end the project.
**3. How should the tutor talk?** Offer these five, each with what it costs. The
first two are the safe defaults; ask which one they want rather than guessing.
| Style | What it is | What it costs |
|---|---|---|
| **Mentor** | Warm, explains in full, notices effort | Long. Impatient people skim it |
| **Coach** | Short, demanding, straight to the task, no praise in advance | Can read as cold on a bad day |
| **Socratic** | Answers with questions, makes you find it | Slowest by far, and maddening in a hurry |
| **Storyteller** | Teaches through stories and comparisons | Comparisons leak — see below |
| **Reference** | Minimum words, facts and structure only | No help at all when you are stuck |
Public assistants have landed on much the same axes — GPT-5 ships Cynic, Robot,
Listener and Nerd; Claude ships Concise, Explanatory and Formal — which is a
reasonable sign these are the ones people actually notice.
⚠️ **Storyteller interacts with a rule already in the core.** Every comparison must
be followed by where it stops working, and this style produces comparisons faster
than any other. Choosing it does not loosen that rule — it makes it the busiest
section on the page. Say so when they pick it.
Record all three as `learner.age_band`, `learner.background`, `tutor.style`, and
**apply them from the very next sentence** — including the greeting that follows.
`learning-track` reads the same fields, so the pages come out in the same voice as
the interview rather than reverting to a house style the learner never chose.
If they later say the voice is wrong, that is a settings change, not a complaint:
edit the field and say what you changed.
## Open with the orientation. Always.
**Before the first question, every time — not only when you have just installed the plugin.** The learner may arrive by any route: a fresh install, an update, a second session, a project someone else set up. If the orientation lives only in the deployment instructions it fires on exactly one of those paths, and on the others the person meets seven questions with no idea what they are for.
Four parts, **in the language settled above and the style just chosen**. Adapt the wording to the subject; keep all four.
1. **What is installed and reachable** — the two skills, the version, and that skills appear only after a session restart.
2. **What this is.** Not a notes folder, and not a thing that summarises books at you. You are going to build two things side by side: **one page per idea**, each explaining that idea three times over — an everyday comparison, then how it is actually used, then the full version — and **a route** through those pages that says out loud why it goes in that order. Each page ends with practice: warm-ups, then problems, with hints you unfold one at a time when you get stuck. Answers live in a separate file so you cannot glance at them. And every page carries a mark saying how well-backed it is, **which a script works out and nobody can type in by hand** — it counts sources and passing checks, not how sure anyone felt.
3. **What they can do with it.** Ask for a route through a topic and get the reasoning, not just a list. Write pages and have claims with no source refused rather than quietly waved through. Get problems designed to break — remove one condition on purpose and watch what stops working, which is how you find out whether that condition was doing real work. Disagree with any line and have it answered: changed, or argued back with reasons, and either way kept on record instead of vanishing into a chat log.
4. **What happens now.** A few questions, then I set up the folders, then you get one page. **That page will come out marked as a draft, and that is correct rather than a failure** — half the rules it would be judged by do not exist yet, because the useful ones only become obvious once real material has pushed back. A second, shorter round of questions afterwards settles those, and everything gets re-marked for real.
Then the preflight results, then the round.
## Then ask what you may look at. Before looking.
The interview is only good because it is grounded in what is actually on the
machine — books on disk, an existing project in the subject, how the learner's
other bases are laid out. That is also a stranger reading through someone's
work. **They have to be asked, and asked before the reading, not after.**
Put it as a structured multiple-choice question with checkboxes, not as prose —
this is a gate, not a conversation, and it should cost one click.
**Question 1, single choice — how far may I look?**
| Option | Means |
|---|---|
| **This directory only** (recommend) | The folder the base will live in, and nothing above or beside it |
| This directory plus folders I name | They list them; you touch nothing else |
| My whole projects directory | Free run of the parent |
| Nothing — ask me instead | You look at no files at all and ask for everything |
**Question 2, multiple choice — what may I read inside them?**
File and folder names only · contents of documents and notes · source code ·
git history.
**State the trade-off in the question itself.** Narrower means a longer round and
more questions whose answers were sitting on the disk — the method still works,
it just asks more. Left unsaid, a learner who restricts the scan reads the extra
questions as the tool being poor.
**Notice what the boundary takes away, and replace it by asking.** Plenty of what
earlier versions inferred — the language, how the learner lays a base out, what
they already own — came from reading their other work. Cut off, those are not lost
facts but unasked questions. Ask them; do not treat a narrow boundary as
permission to guess.
Three rules that make the gate real rather than decorative:
- **Ask before enumerating.** Listing a parent directory to build the checkbox
options is itself the scan being consented to. Offer the choices generically;
only after they pick "folders I name" do you go and list anything.
- **Default to the narrowest** whenever the question cannot be put — a
non-interactive run, no answer. Never widen by assumption.
- **Record it in the domain layer** under `privacy.scan`, and honour it in later
sessions instead of re-asking or, worse, quietly forgetting. `learning-track`
reads the same field.
And be exact about what this is: **a rule you follow, not a sandbox.** The
tooling in `runtime/` never reads outside the project root — every path is
resolved from it — but the boundary above governs *your* reading, and it holds
because you hold it. Say so rather than implying an enforcement that does not
exist.
Note that Q0 of the round — where the base should live — depends on this answer.
Under "this directory only" you cannot go looking for better-named empty
candidates; ask instead.
## Before phase 1: preflight
Check what the machine can actually do, and report it with the greeting. This part
needs no permission — it asks the machine what tools exist (`uv`, a runtime, a
compiler, Tesseract), not the learner's files what they contain.
This is not ceremony — **the answers to Q6 depend on it**, and finding out later
that the checks cannot run turns the trustworthiness scale into decoration.
- `uv` present, or a Python whose `-m venv` can bootstrap pip. Without one of the
two, setup cannot build the project's environment. **Prefer `uv` on every
platform** — it is the difference between seconds and a detour.
- **The platform, and what it changes.** This is not trivia; it changes the
commands you and the learner will type for the rest of the project.
| | What to know |
|---|---|
| **Windows** | No `make`, and the scaffold writes none. Commands are `python tutor.py <command>`. The usual setup failure is the Microsoft Store build of Python, whose `python3` opens the Store and whose `venv` cannot bootstrap pip — recommend python.org Python or `uv`, and recognise the `ensurepip` error for what it is instead of debugging it as ours |
| **macOS** | `make` needs the Xcode command line tools and will *prompt to install them* if missing — a several-minute download in the middle of setup. Do not trigger it: use `python3 tutor.py` |
| **Linux** | Both work. Either form is fine |
The scaffold records the right form in the project's `CLAUDE.md` §0. **Read it
from there rather than assuming `make`**, in this session and every later one.
- For a subject whose checks are executable: does its toolchain run *here*? A
test runner that needs Node 20 on a machine with Node 18 is a blocker for
`strict`, not a detail to mention in passing.
- Whatever else the subject leans on — a compiler, a typechecker, Tesseract for a
book corpus.
Report the blockers **before** asking Q6, and let them change the recommendation.
**Report them; do not halt on them.** A missing runtime is an input to Q6, not a
gate in front of the round — it belongs *inside* the question, as the reason the
recommendation is "standard now, harness first, tighten once a check has passed".
Stopping to demand an infrastructure decision from someone who has not yet been
told what any of this is puts the least interesting choice first and the
orientation last. The exception is a blocker that would make the scaffold itself
fail — no `uv` and no working `venv` — because there is nothing to interview
about until that is fixed.
## Phase 1
Read `references/phase-1.md` for the full question set with recommended answers.
Seven areas: subject and goal · corpus or live sources · **the canon** (who
arbitrates each area, which problem sets, where popular sources are admitted) ·
depth levels · where problems come from · strictness · language and layout.
Output of phase 1:
1. `scaffold.py <root> "<Subject>" [--corpus]` — the tree, the Makefile pointing
at the plugin runtime, the neutral templates.
2. `.tutor/config.yaml` with `phase: 1` — see `references/domain-layer.md`.
3. `CLAUDE.md` — the prose half of the schema, filled in from the interview.
4. `templates/concept.md` — the neutral template **specialised for this subject**:
level names in the subject's own vocabulary, the problem roles as they read
here, the "what breaks if you drop a condition" table renamed if the subject
calls it something else.
Then hand off: "Now write one page — `learning-track` on the concept you would
start with. It will come out `draft`; that is correct."
## Phase 2
Read `references/phase-2.md`. Runs only after at least one real page exists, and
the questions are drawn **from that page**, not from a list. Six areas: independence · attainable check
types · where the format bent · closure criterion · problem supply · **what is
deliberately being left out**, recorded with its reasoning so the same idea is not
re-argued from nothing every few months.
Open phase 2 by reading the page that was written and naming what went wrong in
it. That is the material the whole phase is about.
Output of phase 2:
1. `.tutor/config.yaml` updated, `phase: complete`.
2. `make check` — every page recomputed with the cap lifted. Show the diff in
tags and say plainly which pages did not earn what they were provisionally
given.
## Revising an existing domain layer
The domain layer is **hand-editable on purpose** — it is the learner's judgement
about their own field, unlike `confidence`, which is a machine conclusion. When
they edit it or ask you to, the rule is:
**A change to the thresholds is a migration.** Raise `min_independent_sources`
in June and every page tagged `verified` in March is now wearing a tag it does
not deserve. Always run `make check` straight after, always show what dropped,
never let the change land silently.
## The five types of check are fixed
`formal` · `behavioral` · `illustrative` · `attested` · `contested`. A domain
declares which of them it can **attain**; it never invents a sixth. If a subject
seems to need one, that is a finding about the core worth reporting, not a
config value to make up.
The one to reach for in fields with nothing to execute is **`attested`**: it
verifies not that the claim is true but that the source was not misquoted —
the only thing a machine can honestly certify about a documentary claim, and
enough to keep the scale alive in history, law, or medicine.