2026– · Independent project
exam-nation
Misconception-driven Socratic maths tutoring across two live GCSE courses.
What it is
A GCSE maths tutor organised around misconceptions rather than topics. The catalogue behind it is a list of specific wrong mental models, but a student never sees that list. They see topics, and the misconception layer decides what happens inside a lesson.
The route through it is a twenty-question diagnostic taken without an account, a report that ranks the weak topics into one to start with and some to revisit, a deeper diagnostic on the topic they pick, and then a single-sitting lesson that climbs from basics to exam-level work. Two courses, Foundation and Higher, run from one codebase and are routed by hostname.
The problem
A student who reads a gradient the wrong way round does not have a gap. They have a rule, and it is wrong, and it works often enough that they trust it. Reteaching the topic leaves the rule intact. So the unit of work has to be the misconception, not the syllabus.
The engineering problem that follows is trust. An LLM asked to tutor freely will give the answer away, invent pedagogy, or walk a student into the wrong operation in order to correct it afterwards. None of that is acceptable in front of a child sitting an exam.
How it works
Teaching content is code, not prompts. The misconception catalogue, the Socratic scripts and the levelled lessons are TypeScript and markdown compiled into the build; the database holds student state only. The climb does not duplicate that content, it re-orders it: a topic plan pulls the same scripts at each level.
Inside a level the pattern is check first, teach only on a miss. A student who clears the check moves up without being taught at all, and the verdict at the end of a climb reports the highest level they cleared with no teaching fired.
The tutoring turn itself is deliberately constrained. The model is told it is running a state machine and does not decide the dialogue: the script decides, and the model matches and emits. Each turn ends with a hidden state block that the server parses and persists, so progression is tracked in the database rather than inferred from chat history. Every model call goes through one audited helper that caches the system prompt and records tokens, latency and estimated cost, so a prompt change has a visible price.
Retakes rotate five parallel forms of the diagnostic, so a second sitting is not the same twenty questions.
What I’d change
Compiling the content in is the decision I would revisit. The intervention registry hard-codes an import per lesson file, which is why a missing file fails the build rather than failing a lesson in front of a student. It also means correcting one sentence of teaching copy needs a rebuild and a deploy. That is the right trade for correctness and the wrong one for iteration speed.
The billing path is the least exercised code in the project. The paywall threshold constant is set to zero, which switches the paywall off outright, so the entitlement and checkout machinery is built and tested but is not currently in any student’s way.