07 / In development · iPhone
Reading
Helper
The curriculum is the product. The validator is why I trust it.
A native iPhone app that teaches a three-year-old to read the way reading actually starts: not flashcards, not sight words, but noticing sounds, meeting the letters that spell them, and blending them together — five minutes at a time, with a parent doing the teaching and the app doing the coaching. The bet is that a parent who doesn’t know phonics terminology can still teach reading well, if the app says exactly what to say and exactly what sound to model.
The part worth explaining isn’t the lesson content. It’s that almost none of “is this lesson correct” is a judgement call anymore. It’s a build failure. The name is still a working title; the curriculum is the thing that’s real.
Content is data. One screen plays a lesson.
There is no Swift file for “the /m/ lesson” or “the rhyming lesson.” Lessons, activities, and skills are JSON, and the app contains one generic lesson player plus one renderer per activity primitive — listen and choose, sound basket, read and reveal, and seven others. Wanting custom behaviour for one specific lesson is a signal that a new primitive is needed, not an excuse to special-case a screen. Ten primitives currently cover a twelve-lesson curriculum without a single bespoke view, so new lessons are content commits rather than code changes.
The validator is the actual author of quality here
One content-engine package owns every rule — schema shape, dangling references, prerequisite cycles, audio policy, personalisation fields — and both the app and a command-line tool run the exact same pipeline. Every rule reports a stable code, and a mode decides whether that code is a warning or a hard failure. Dev mode lets me keep building with placeholders visible; release mode refuses to ship one. A test proves the two modes report identical findings and differ only in severity, so nobody can quietly special-case dev mode into skipping a rule.
EVERY LESSON GOES THROUGH THIS BEFORE A CHILD SEES IT.
- CONTENT JSONLessons, activities, and skills as data.
- INTEGRITYSchema, dangling IDs, cycles, missing assets.
- CURRICULUMOne correct choice; continuant-first blending; no guessing prompts.
- AUDIO POLICYTier, schwa flags, approval state.
- DEV / RELEASEDev downgrades findings to warnings. Release makes them hard failures.
The rule I’m proudest of: no activity, hint, or parent script may ever say “look at the picture” or “what word would make sense” to identify a word. That is the textbook strategy of a struggling reader, and it is now a failure the validator catches on real content — not a style guideline somebody has to remember at eleven at night.
A model can generate the audio. Only I can approve it.
Every sound a child imitates precisely — an isolated phoneme, a blended word — is top-tier audio, and top-tier audio can be a generated candidate, but it can only be approved by a human listening to it, one asset at a time. There is no bulk approval path and no code path that can mark one approved on my behalf.
The reason isn’t ceremony. A text-to-speech model reads “t” as often as not with a voiced “uh” tail — a schwa — and a corrupted /t/ teaches a child to blend “tuh-at” instead of “t-at.” No automated check can hear that. My ear at the point of approval is the actual safeguard, and the architecture makes that literal: an unapproved top-tier asset fails the build in both modes, permanently.
No gamification, structurally
No emoji, no scores, no streaks, no red failure states, anywhere — there is a test that scans every Swift file and every content string for the emoji Unicode blocks and fails the build if it finds one. Missing a tap after two tries doesn’t produce a failure state; it produces an offer to move on together, logged as “not yet,” which never demotes anything.
Every lesson also has to be complete and delightful with zero photos and zero recordings, because personalisation is layered on top of a stock baseline and never required by it — enforced by an empty-state test on every single renderer.
WHAT IT TAUGHT ME
The interesting engineering problem in a “simple” kids’ app isn’t the UI. It’s that the actual research about how children learn to read is full of specific, falsifiable rules — no schwa, no guessing, no whole-word memorisation — and almost every one of them can be encoded as a validator check instead of a design-review habit. The app is only as trustworthy as the thing standing between the content and the child, and here that thing is a compiler-enforced rule rather than my attention span at 11pm.