the-teacher
by outlast85
README.md
# The Teacher
Run learning as a **verified loop**: interview to build a detailed **Target** (your goal as
observable claims), derive a **Path** to close the gap, learn through **teach → lab → test →
gate** per claim, get **cold-examined** by an adversarial verifier, and **raise the Target** once
you match it. A generic engine; ships with a guitar-learning example.
It's a small **MCP server + Claude Code skill**. The coaching agent teaches; a separate
**fresh-context examiner subagent** grades — so the teacher never certifies itself.
## Quickstart
```bash
python3 -m venv .venv && .venv/bin/pip install "mcp[cli]" pytest
.venv/bin/pytest # all green
THE_TEACHER_STORE=./store.local.json .venv/bin/python server.py
```
See **Install** below to add it to Claude Code.
## Install as a plugin (one step) — recommended
The repo is its own plugin marketplace, so Claude Code can install the server **and** the skill
together. Requires [`uv`](https://docs.astral.sh/uv/) on your PATH (it pulls the `mcp` dependency
on the fly — no venv to manage).
```
/plugin marketplace add outlast85/the-teacher
/plugin install the-teacher@the-teacher
```
The coaching skill is then available as `/the-teacher:teacher`.
## Install manually
If you'd rather wire it up by hand (or don't use `uv`):
```bash
git clone https://github.com/outlast85/the-teacher.git
cd the-teacher
python3 -m venv .venv && .venv/bin/pip install "mcp[cli]"
# 1) register the MCP server (per-user; the `--` separator is required)
claude mcp add --transport stdio the-teacher -- "$PWD/.venv/bin/python" "$PWD/server.py"
# 2) install the coaching skill
mkdir -p ~/.claude/skills/teacher && cp skills/teacher/SKILL.md ~/.claude/skills/teacher/SKILL.md
```
There is no global MCP list — registration is **per-user and local**. Confirm with
`claude mcp list`.
## How it works
1. **First run** — the coach calls `status()`, and if no Target is set it **interviews you
first**: it probes your real goal, decomposes it into 2–6 claims with observable
`pass_criteria`, tags each claim `needs_lab` (runnable/software claims require lab evidence to
pass), dispatches a fresh-context subagent to review the drafted Target for specificity, then
calls `set_target`. **A detailed Target is required before any teaching begins.**
2. **Teach → lab → test → gate per claim** — for each module the coach teaches the concept,
runs a lab if `needs_lab=true` (recording evidence with `record_progress`), asks you to
explain the claim cold, dispatches a fresh-context examiner subagent to grade blind, and calls
`record_verdict`. A `needs_lab` claim with no logged lab evidence is coerced to non-pass by
the server even if the examiner says passed. The claim stays in `derive_path` until it
genuinely passes the gate.
3. **Raise the Target** — when `status().matched` is true, the coach congratulates you and
offers a harder Target, restarting the loop.
## Verifier-independence (the design point)
The examiner is deliberately adversarial (default-to-not-ready, high field standard). What makes
the verdict *independent* of the teacher is **context isolation** — and that's the only mechanism:
- **The verifier is a fresh-context examiner subagent.** The coach asks the learner to explain the
module cold, then dispatches a SEPARATE subagent (same model, **clean context**) whose prompt
contains ONLY the claim, the pass criteria, the learner's explanation, and any lab evidence —
never the coaching conversation. Because that examiner never saw the context it would otherwise
be anchored on, the grade is genuinely decorrelated: real **maker/checker**, not Reflection. The
coach records it via `record_verdict(..., verdict_source="fresh-context")`. This works for
**any** subject, needs **zero config**, no second model, and no external service.
- **Discouraged — `same-context`:** inline grading in the same coaching conversation. If ever
used, it's recorded as `verdict_source="same-context"` and `status()` raises an
`only_same_context` warning when a match is backed solely by it. This is the weak-verifier
case; avoid it.
`matched` in `status` counts `fresh-context` verdicts. The server itself never calls any model —
all grading is done by the subagent inside your own client.
Resource URIs use the `theteacher://` scheme (e.g. `theteacher://target`,
`theteacher://path`, `theteacher://progress`).
## Privacy
Your Target/Path/progress live in a local JSON store (`~/.the-teacher/store.json` by default,
overridden by `THE_TEACHER_STORE`) that is **gitignored**. The repo ships only the generic
example. No personal data is ever committed.
TDQS
A3.5/5.0
Scored across 6 tools
Disambiguation5/5
Each tool has a distinct purpose: derive_path generates learning paths, load_target loads targets, record_progress logs attempts, record_verdict records exam verdicts, set_target stores goals, and status reports coverage. No overlap.
Naming Consistency4/5
Most tools follow verb_noun pattern (derive_path, load_target, record_progress, record_verdict, set_target). 'status' is a single noun but is a common exception.
Tool Count5/5
Six tools is well-scoped for the domain of managing learning targets and progress. Neither too few nor too many.
Completeness5/5
The tool set covers the full workflow: setting targets, loading them, deriving paths for uncovered claims, recording progress and verdicts, and reporting status. No obvious gaps.
Maintenance
ActivityInactive
ResponsivenessNo issues